From 1060baf74b3d480d026a3d88e9c4b2d4aae118a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Thu, 2 Apr 2020 11:33:22 +0200 Subject: [PATCH] HHH-13682 Enable extended bytecode enhancement in NaturalIdInUninitializedAssociationTest This test accesses a field of an entity directly and expects it to be automatically initialized; this cannot work without extended bytecode enhancement. This used to work with Java 8 bytecode, but only by chance. It seems that Java 8 bytecode relies on "synthetic", static access methods inserted by the compiler to access the fields of entities in this test: any access to the field is done through this access method instead of through a direct field access. Since we apply bytecode enhancement to all methods of entities, this means that access to fields triggers initialization, without any bytecode enhancement in the caller class. I believe this is specific to nested classes, but couldn't find a source. For reference, the bytecode of access methods looks like this: static int access$002(org.hibernate.test.bytecode.enhancement.lazy.NaturalIdInUninitializedAssociationTest$AnEntity, int); Code: 0: aload_0 1: iload_1 2: dup_x1 3: putfield #3 // Field id:I 6: ireturn static org.hibernate.test.bytecode.enhancement.lazy.NaturalIdInUninitializedAssociationTest$EntityImmutableNaturalId access$102(org.hibernate.test.bytecode.enhancement.lazy.NaturalIdInUninitializedAssociationTest$AnEntity, org.hibernate.test.bytecode.enhancement.lazy.NaturalIdInUninitializedAssociationTest$EntityImmutableNaturalId); Code: 0: aload_0 1: aload_1 2: dup_x1 3: putfield #2 // Field entityImmutableNaturalId:Lorg/hibernate/test/bytecode/enhancement/lazy/NaturalIdInUninitializedAssociationTest$EntityImmutableNaturalId; 6: areturn With Java 11, however, access to fields of entities is done directly, even for nested classes. So the access methods no longer exist, and we don't get automatic initialization upon field access. We need extended bytecode enhancement, like we would in any other case of field access (in particular accessing fields of non-nested classes). --- .../lazy/NaturalIdInUninitializedAssociationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/NaturalIdInUninitializedAssociationTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/NaturalIdInUninitializedAssociationTest.java index 1f86b4aa83..3e9ede028f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/NaturalIdInUninitializedAssociationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/NaturalIdInUninitializedAssociationTest.java @@ -39,7 +39,7 @@ import static org.junit.Assert.assertFalse; @SuppressWarnings({"unused", "WeakerAccess","ResultOfMethodCallIgnored"}) @TestForIssue( jiraKey = "HHH-13607" ) @RunWith( BytecodeEnhancerRunner.class ) -@EnhancementOptions( lazyLoading = true ) +@EnhancementOptions( lazyLoading = true, extendedEnhancement = true ) public class NaturalIdInUninitializedAssociationTest extends BaseNonConfigCoreFunctionalTestCase { @Test