Skip to content

Commit cf6d1dd

Browse files
dreab8vladmihalcea
authored andcommitted
HHH-11716 - @transient annotation not respected when class defines 'get' and 'is' accessor variants
1 parent 0e83628 commit cf6d1dd

File tree

2 files changed

+161
-4
lines changed

2 files changed

+161
-4
lines changed

hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import java.util.Locale;
1616
import java.util.regex.Pattern;
1717

18+
import javax.persistence.Transient;
19+
1820
import org.hibernate.AssertionFailure;
1921
import org.hibernate.MappingException;
2022
import org.hibernate.PropertyNotFoundException;
@@ -451,6 +453,10 @@ private static Method getGetterOrNull(Class containerClass, String propertyName)
451453
continue;
452454
}
453455

456+
if ( method.getAnnotation( Transient.class ) != null ) {
457+
continue;
458+
}
459+
454460
final String methodName = method.getName();
455461

456462
// try "get"
@@ -486,9 +492,11 @@ private static void verifyNoIsVariantExists(
486492
// verify that the Class does not also define a method with the same stem name with 'is'
487493
try {
488494
final Method isMethod = containerClass.getDeclaredMethod( "is" + stemName );
489-
// No such method should throw the caught exception. So if we get here, there was
490-
// such a method.
491-
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
495+
if ( isMethod.getAnnotation( Transient.class ) == null ) {
496+
// No such method should throw the caught exception. So if we get here, there was
497+
// such a method.
498+
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
499+
}
492500
}
493501
catch (NoSuchMethodException ignore) {
494502
}
@@ -526,7 +534,9 @@ private static void verifyNoGetVariantExists(
526534
final Method getMethod = containerClass.getDeclaredMethod( "get" + stemName );
527535
// No such method should throw the caught exception. So if we get here, there was
528536
// such a method.
529-
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
537+
if ( getMethod.getAnnotation( Transient.class ) == null ) {
538+
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
539+
}
530540
}
531541
catch (NoSuchMethodException ignore) {
532542
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.property;
8+
9+
import javax.persistence.Entity;
10+
import javax.persistence.Id;
11+
import javax.persistence.Table;
12+
import javax.persistence.Transient;
13+
14+
import org.hibernate.testing.TestForIssue;
15+
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
16+
import org.hibernate.testing.transaction.TransactionUtil;
17+
import org.junit.Test;
18+
19+
import static org.hamcrest.core.Is.is;
20+
import static org.hamcrest.core.IsNull.nullValue;
21+
import static org.junit.Assert.assertThat;
22+
23+
/**
24+
* @author Andrea Boriero
25+
*/
26+
@TestForIssue(jiraKey = "HHH-11716")
27+
public class GetAndIsVariantGetterWithTransientAnnotationTest extends BaseCoreFunctionalTestCase {
28+
29+
@Override
30+
protected Class<?>[] getAnnotatedClasses() {
31+
return new Class[] {TestEntity.class, SecondTestEntity.class};
32+
}
33+
34+
@Test
35+
public void testGetAndIsVariantCanHaveDifferentReturnValueWhenOneHasATransientAnnotation() {
36+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
37+
TestEntity entity = new TestEntity();
38+
entity.setId( 1L );
39+
entity.setChecked( true );
40+
session1.save( entity );
41+
} );
42+
43+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
44+
final TestEntity entity = session1.find( TestEntity.class, 1L );
45+
assertThat( entity.isChecked(), is( true ) );
46+
} );
47+
48+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
49+
final TestEntity entity = session1.find( TestEntity.class, 1L );
50+
entity.setChecked( null );
51+
} );
52+
53+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
54+
final TestEntity entity = session1.find( TestEntity.class, 1L );
55+
assertThat( entity.isChecked(), is( nullValue() ) );
56+
} );
57+
}
58+
59+
@Test
60+
public void testBothGetterAndIsVariantAreIgnoredWhenMarkedTransient() {
61+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
62+
SecondTestEntity entity = new SecondTestEntity();
63+
entity.setId( 1L );
64+
entity.setChecked( true );
65+
session1.save( entity );
66+
} );
67+
68+
TransactionUtil.doInHibernate( this::sessionFactory, session1 -> {
69+
final SecondTestEntity entity = session1.find( SecondTestEntity.class, 1L );
70+
assertThat( entity.getChecked(), is( nullValue() ) );
71+
} );
72+
}
73+
74+
@Entity(name = "TestEntity")
75+
@Table(name = "TEST_ENTITY")
76+
public static class TestEntity {
77+
private Long id;
78+
private Boolean checked;
79+
private String name;
80+
81+
@Id
82+
public Long getId() {
83+
return id;
84+
}
85+
86+
public void setId(Long id) {
87+
this.id = id;
88+
}
89+
90+
public void setChecked(Boolean checked) {
91+
this.checked = checked;
92+
}
93+
94+
@Transient
95+
public boolean getChecked() {
96+
return false;
97+
}
98+
99+
public Boolean isChecked() {
100+
return this.checked;
101+
}
102+
103+
public String getName() {
104+
return name;
105+
}
106+
107+
public void setName(String name) {
108+
this.name = name;
109+
}
110+
111+
@Transient
112+
public boolean isName() {
113+
return name.length() > 0;
114+
}
115+
}
116+
117+
@Entity(name = "SecondTestEntity")
118+
@Table(name = "TEST_ENTITY_2")
119+
public static class SecondTestEntity {
120+
private Long id;
121+
private Boolean checked;
122+
123+
@Id
124+
public Long getId() {
125+
return id;
126+
}
127+
128+
public void setId(Long id) {
129+
this.id = id;
130+
}
131+
132+
public void setChecked(Boolean checked) {
133+
this.checked = checked;
134+
}
135+
136+
@Transient
137+
public Boolean getChecked() {
138+
return this.checked;
139+
}
140+
141+
@Transient
142+
public boolean isChecked() {
143+
return false;
144+
}
145+
}
146+
147+
}

0 commit comments

Comments
 (0)