11package org .hibernate .orm .test .bytecode .enhancement .access ;
22
3- import jakarta .persistence .*;
3+ import jakarta .persistence .Access ;
4+ import jakarta .persistence .AccessType ;
5+ import jakarta .persistence .Basic ;
6+ import jakarta .persistence .Entity ;
7+ import jakarta .persistence .Id ;
8+ import jakarta .persistence .Table ;
9+ import jakarta .persistence .Transient ;
410import org .hibernate .testing .bytecode .enhancement .extension .BytecodeEnhanced ;
5- import org .hibernate .testing .orm .junit .*;
11+ import org .hibernate .testing .orm .junit .DomainModel ;
12+ import org .hibernate .testing .orm .junit .FailureExpected ;
13+ import org .hibernate .testing .orm .junit .JiraKey ;
14+ import org .hibernate .testing .orm .junit .SessionFactory ;
15+ import org .hibernate .testing .orm .junit .SessionFactoryScope ;
616import org .junit .jupiter .api .AfterEach ;
717import org .junit .jupiter .api .Test ;
818
1121@ DomainModel (
1222 annotatedClasses = {
1323 InvalidPropertyNameTest .SomeEntity .class ,
24+ InvalidPropertyNameTest .SomeEntityWithFalsePositive .class
1425 }
1526)
1627@ SessionFactory
17- @ JiraKey ("HHH-16572" )
1828@ BytecodeEnhanced
1929public class InvalidPropertyNameTest {
2030
2131
2232 @ Test
2333 @ FailureExpected (jiraKey = "HHH-16572" )
34+ @ JiraKey ("HHH-16572" )
2435 public void test (SessionFactoryScope scope ) {
2536 scope .inTransaction ( session -> {
2637 session .persist ( new SomeEntity ( 1L , "field" , "property" ) );
@@ -39,15 +50,40 @@ public void test(SessionFactoryScope scope) {
3950 } );
4051 }
4152
53+ @ Test
54+ @ JiraKey ("HHH-18832" )
55+ public void testNoFalsePositive (SessionFactoryScope scope ) {
56+ scope .inTransaction ( session -> {
57+ session .persist ( new SomeEntityWithFalsePositive ( 1L , "property1-initial" , "property2-initial" ) );
58+ } );
59+
60+ // Before HHH-18832 was fixed, lazy-loading enhancement was (incorrectly) skipped,
61+ // resulting at best in `property1` being null in the code below,
62+ // at worst in other errors such as java.lang.NoSuchMethodError: 'java.lang.String org.hibernate.orm.test.bytecode.enhancement.access.InvalidPropertyNameTest$SomeEntityWithFalsePositive.$$_hibernate_read_property1()'
63+ // (see https://hibernate.zulipchat.com/#narrow/channel/132094-hibernate-orm-dev/topic/HHH-16572/near/481330806)
64+ scope .inTransaction ( session -> {
65+ SomeEntityWithFalsePositive entity = session .getReference ( SomeEntityWithFalsePositive .class , 1L );
66+ // Lazy-loading triggered by field access
67+ // Proves bytecode enhancement is effective
68+ assertThat ( entity .property1 ).isEqualTo ( "property1-initial" );
69+ } );
70+
71+ scope .inTransaction ( session -> {
72+ SomeEntityWithFalsePositive entity = session .getReference ( SomeEntityWithFalsePositive .class , 1L );
73+ // Proves bytecode enhancement is effective even for the transient method
74+ assertThat ( entity .getProperty () ).isEqualTo ( "property1-initial property2-initial" );
75+ } );
76+ }
77+
4278 @ AfterEach
4379 public void cleanup (SessionFactoryScope scope ) {
44- // uncomment the following when @FailureExpected is removed above
45- // scope.inTransaction( session -> {
46- // session.remove( session.get( SomeEntity.class, 1L ) );
47- // PropertyAccessTest } );
80+ scope . inTransaction ( session -> {
81+ session . createQuery ( "delete from SomeEntity" ). executeUpdate ();
82+ session .createQuery ( "delete from SomeEntityWithFalsePositive" ). executeUpdate ( );
83+ } );
4884 }
4985
50- @ Entity
86+ @ Entity ( name = "SomeEntity" )
5187 @ Table (name = "SOME_ENTITY" )
5288 static class SomeEntity {
5389 @ Id
@@ -84,4 +120,53 @@ public void setPropertyMethod(String property) {
84120 this .property = property ;
85121 }
86122 }
123+
124+ @ Entity (name = "SomeEntityWithFalsePositive" )
125+ static class SomeEntityWithFalsePositive {
126+
127+ private Long id ;
128+
129+ private String property1 ;
130+
131+ private String property2 ;
132+
133+ public SomeEntityWithFalsePositive () {
134+ }
135+
136+ public SomeEntityWithFalsePositive (Long id , String property1 , String property2 ) {
137+ this .id = id ;
138+ this .property1 = property1 ;
139+ this .property2 = property2 ;
140+ }
141+
142+ @ Id
143+ public long getId () {
144+ return id ;
145+ }
146+
147+ public void setId (long id ) {
148+ this .id = id ;
149+ }
150+
151+ public String getProperty1 () {
152+ return property1 ;
153+ }
154+
155+ public void setProperty1 (String property1 ) {
156+ this .property1 = property1 ;
157+ }
158+
159+ public String getProperty2 () {
160+ return property2 ;
161+ }
162+
163+ public void setProperty2 (String property2 ) {
164+ this .property2 = property2 ;
165+ }
166+
167+ @ Transient
168+ public String getProperty () {
169+ return property1 + " " + property2 ;
170+ }
171+ }
87172}
0 commit comments