diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingDynamicUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingDynamicUpdateTest.java new file mode 100644 index 0000000000..3a3981e46b --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingDynamicUpdateTest.java @@ -0,0 +1,364 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.test.bytecode.enhancement.lazy.proxy; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.Hibernate; +import org.hibernate.annotations.DynamicUpdate; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; +import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; +import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Gail Badner + */ +@TestForIssue( jiraKey = "HHH-13640" ) +@RunWith(BytecodeEnhancerRunner.class) +@EnhancementOptions(lazyLoading = true,inlineDirtyChecking = true) +public class ProxyInitializeAndUpdateInlineDirtyTrackingDynamicUpdateTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { + super.configureStandardServiceRegistryBuilder( ssrb ); + ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" ); + } + + @Override + protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) { + super.configureSessionFactoryBuilder( sfb ); + sfb.applyStatisticsSupport( true ); + sfb.applySecondLevelCacheSupport( false ); + sfb.applyQueryCacheSupport( false ); + } + + @Override + protected void applyMetadataSources(MetadataSources sources) { + super.applyMetadataSources( sources ); + sources.addAnnotatedClass( Animal.class ); + } + + @Test + public void testInitializeWithGetter() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + animal.color = "green"; + session.persist( animal ); + } + ); + + inTransaction( + session -> { + Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( 3, animal.getAge() ); + animal.setSex( "other" ); + } + ); + + inSession( + session -> { + Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + assertEquals( "green", animal.getColor() ); + } + ); + } + + @Test + public void testInitializeWithSetter() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + animal.color = "green"; + session.persist( animal ); + } + ); + + inTransaction( + session -> { + Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + animal.setSex( "other" ); + // Setting the attribute value should not initialize animal + // with dirty-checking and dynamic-update. + assertFalse( Hibernate.isInitialized( animal ) ); + } + ); + + inSession( + session -> { + Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( "green", animal.getColor() ); + assertEquals( 3, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUpdatedOntoUninitialized() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalInitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + return animal; + } + ); + + animalInitialized.setAge( 4 ); + animalInitialized.setSex( "other" ); + + inTransaction( + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + session.merge( animalInitialized ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( 4, animal.getAge() ); + assertEquals( "other", animal.getSex() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUpdatedOntoUpdated() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalInitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + return animal; + } + ); + + animalInitialized.setAge( 4 ); + animalInitialized.setSex( "other" ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + animal.setAge( 5 ); + animal.setSex( "male" ); + session.merge( animalInitialized ); + assertEquals( 4, animal.getAge() ); + assertEquals( "other", animal.getSex() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUninitializedOntoUninitialized() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalUninitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + return animal; + } + ); + + inTransaction( + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + session.merge( animalUninitialized ); + assertFalse( Hibernate.isInitialized( animal ) ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUninitializedOntoUpdated() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalUninitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + return animal; + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + animal.setSex( "other" ); + animal.setAge( 4 ); + session.merge( animalUninitialized ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @After + public void cleanUpTestData() { + inTransaction( + session -> { + session.createQuery( "delete from Animal" ).executeUpdate(); + } + ); + } + + @Entity(name = "Animal") + @Table(name = "Animal") + @DynamicUpdate + public static class Animal { + + @Id + private String name; + + private int age; + + private String sex; + + private String color; + + public String getName() { + return name; + } + + protected void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingTest.java new file mode 100644 index 0000000000..67f458b065 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateInlineDirtyTrackingTest.java @@ -0,0 +1,361 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.test.bytecode.enhancement.lazy.proxy; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.Hibernate; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.AvailableSettings; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; +import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; +import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Gail Badner + */ +@TestForIssue( jiraKey = "HHH-13640" ) +@RunWith(BytecodeEnhancerRunner.class) +@EnhancementOptions(lazyLoading = true,inlineDirtyChecking = true) +public class ProxyInitializeAndUpdateInlineDirtyTrackingTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { + super.configureStandardServiceRegistryBuilder( ssrb ); + ssrb.applySetting( AvailableSettings.ALLOW_ENHANCEMENT_AS_PROXY, "true" ); + } + + @Override + protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) { + super.configureSessionFactoryBuilder( sfb ); + sfb.applyStatisticsSupport( true ); + sfb.applySecondLevelCacheSupport( false ); + sfb.applyQueryCacheSupport( false ); + } + + @Override + protected void applyMetadataSources(MetadataSources sources) { + super.applyMetadataSources( sources ); + sources.addAnnotatedClass( Animal.class ); + } + + @Test + public void testInitializeWithGetter() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + animal.color = "green"; + session.persist( animal ); + } + ); + + inTransaction( + session -> { + Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( 3, animal.getAge() ); + animal.setSex( "other" ); + } + ); + + inSession( + session -> { + Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + assertEquals( "green", animal.getColor() ); + } + ); + } + + @Test + public void testInitializeWithSetter() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + animal.color = "green"; + session.persist( animal ); + } + ); + + inTransaction( + session -> { + Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + animal.setSex( "other" ); + // Setting the attribute value should have initialized animal. + assertTrue( Hibernate.isInitialized( animal ) ); + } + ); + + inSession( + session -> { + Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( "green", animal.getColor() ); + assertEquals( 3, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUpdatedOntoUninitialized() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalInitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + return animal; + } + ); + + animalInitialized.setAge( 4 ); + animalInitialized.setSex( "other" ); + + inTransaction( + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + session.merge( animalInitialized ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( 4, animal.getAge() ); + assertEquals( "other", animal.getSex() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUpdatedOntoUpdated() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalInitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + return animal; + } + ); + + animalInitialized.setAge( 4 ); + animalInitialized.setSex( "other" ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + animal.setAge( 5 ); + animal.setSex( "male" ); + session.merge( animalInitialized ); + assertEquals( 4, animal.getAge() ); + assertEquals( "other", animal.getSex() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUninitializedOntoUninitialized() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalUninitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + return animal; + } + ); + + inTransaction( + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + session.merge( animalUninitialized ); + assertFalse( Hibernate.isInitialized( animal ) ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "female", animal.getSex() ); + assertEquals( 3, animal.getAge() ); + } + ); + } + + @Test + public void testMergeUninitializedOntoUpdated() { + inTransaction( + session -> { + Animal animal = new Animal(); + animal.name = "animal"; + animal.age = 3; + animal.sex = "female"; + session.persist( animal ); + } + ); + + final Animal animalUninitialized = doInHibernate( + this::sessionFactory, + session -> { + final Animal animal = session.load( Animal.class, "animal" ); + assertFalse( Hibernate.isInitialized( animal ) ); + return animal; + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + animal.setSex( "other" ); + animal.setAge( 4 ); + session.merge( animalUninitialized ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + + inTransaction( + session -> { + final Animal animal = session.get( Animal.class, "animal" ); + assertTrue( Hibernate.isInitialized( animal ) ); + assertEquals( "other", animal.getSex() ); + assertEquals( 4, animal.getAge() ); + } + ); + } + + @After + public void cleanUpTestData() { + inTransaction( + session -> { + session.createQuery( "delete from Animal" ).executeUpdate(); + } + ); + } + + @Entity(name = "Animal") + @Table(name = "Animal") + public static class Animal { + + @Id + private String name; + + private int age; + + private String sex; + + private String color; + + public String getName() { + return name; + } + + protected void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateTest.java index bfafecb138..562d68bc40 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/ProxyInitializeAndUpdateTest.java @@ -16,9 +16,9 @@ import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.testing.FailureExpected; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner; +import org.hibernate.testing.bytecode.enhancement.EnhancementOptions; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.junit.After; import org.junit.Test; @@ -34,6 +34,7 @@ import static org.junit.Assert.assertTrue; */ @TestForIssue( jiraKey = "HHH-13640" ) @RunWith(BytecodeEnhancerRunner.class) +@EnhancementOptions(lazyLoading = true) public class ProxyInitializeAndUpdateTest extends BaseNonConfigCoreFunctionalTestCase { @Override protected void configureStandardServiceRegistryBuilder(StandardServiceRegistryBuilder ssrb) { @@ -108,6 +109,8 @@ public class ProxyInitializeAndUpdateTest extends BaseNonConfigCoreFunctionalTes Animal animal = session.load( Animal.class, "animal" ); assertFalse( Hibernate.isInitialized( animal ) ); animal.setSex( "other" ); + // Setting the attribute value should have initialized animal. + assertTrue( Hibernate.isInitialized( animal ) ); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/SimpleUpdateTestWithLazyLoading.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/SimpleUpdateTestWithLazyLoading.java index 6f31d92af6..fa896483fd 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/SimpleUpdateTestWithLazyLoading.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/proxy/SimpleUpdateTestWithLazyLoading.java @@ -25,12 +25,9 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor; import org.hibernate.cfg.AvailableSettings; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.engine.spi.CollectionKey; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptor; -import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.stat.Statistics; @@ -200,8 +197,12 @@ public class SimpleUpdateTestWithLazyLoading extends BaseNonConfigCoreFunctional doInHibernate( this::sessionFactory, s -> { Child loadedChild = s.load( Child.class, lastChildID ); + assertThat( Hibernate.isInitialized( loadedChild ), is( false ) ); assertThat( loadedChild.getName(), is( updatedName ) ); + assertThat( Hibernate.isInitialized( loadedChild ), is( true ) ); + assertThat( Hibernate.isInitialized( loadedChild.getParent() ), is( false ) ); assertThat( loadedChild.getParent().getName(), is( parentName ) ); + assertThat( Hibernate.isInitialized( loadedChild.getParent() ), is( true ) ); } ); } @@ -216,7 +217,9 @@ public class SimpleUpdateTestWithLazyLoading extends BaseNonConfigCoreFunctional assertEquals( 0, stats.getPrepareStatementCount() ); Person relative = new Person(); relative.setName( "Luis" ); + assertThat( Hibernate.isInitialized( loadedChild ), is( false ) ); loadedChild.addRelative( relative ); + assertThat( Hibernate.isInitialized( loadedChild ), is( true ) ); assertEquals( 2, stats.getPrepareStatementCount() ); s.persist( relative ); } );