diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaFlushEntityEventListener.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaFlushEntityEventListener.java index 083e06abda..f73c24988c 100644 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaFlushEntityEventListener.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/event/internal/core/JpaFlushEntityEventListener.java @@ -62,8 +62,9 @@ public class JpaFlushEntityEventListener extends DefaultFlushEntityEventListener int size = newState.length; boolean isDirty = false; for ( int index = 0; index < size ; index++ ) { - if (state[index] == LazyPropertyInitializer.UNFETCHED_PROPERTY && newState[index] != LazyPropertyInitializer.UNFETCHED_PROPERTY - || state[index] != newState[index] && !types[index].isEqual(state[index], newState[index])) { + if ( ( state[index] == LazyPropertyInitializer.UNFETCHED_PROPERTY && + newState[index] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) || + ( state[index] != newState[index] && !types[index].isEqual( state[index], newState[index] ) ) ) { isDirty = true; state[index] = newState[index]; } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/CallbacksTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/CallbacksTest.java index 315d27eb8e..58b8b211c5 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/CallbacksTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/CallbacksTest.java @@ -13,11 +13,14 @@ import javax.persistence.EntityManager; import org.junit.Test; +import org.hibernate.Hibernate; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.jpa.test.Cat; import org.hibernate.jpa.test.Kitten; import org.hibernate.testing.FailureExpected; +import org.hibernate.testing.TestForIssue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -263,6 +266,7 @@ public class CallbacksTest extends BaseEntityManagerFunctionalTestCase { * @throws Exception */ @Test + @TestForIssue( jiraKey = "HHH-7573" ) public void testJpaFlushEntityEventListener() throws Exception { EntityWithLazyProperty entity; EntityManager em = getOrCreateEntityManager(); @@ -276,16 +280,23 @@ public class CallbacksTest extends BaseEntityManagerFunctionalTestCase { entity.setLazyData(testArray); em.persist(entity); em.getTransaction().commit(); + em.close(); + checkLazyField(entity, em, testArray); /** * Set a non lazy field, therefore the lazyData field will be LazyPropertyInitializer.UNFETCHED_PROPERTY * for both state and newState so the field should not change. This should no longer cause a ClassCastException. */ + em = getOrCreateEntityManager(); em.getTransaction().begin(); entity = em.find(EntityWithLazyProperty.class, entity.getId()); entity.setSomeField("TEST1"); + assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); em.getTransaction().commit(); + assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); + em.close(); + checkLazyField(entity, em, testArray); /** @@ -293,11 +304,16 @@ public class CallbacksTest extends BaseEntityManagerFunctionalTestCase { * PreUpdate annotated callback method. So state == LazyPropertyInitializer.UNFETCHED_PROPERTY and * newState == EntityWithLazyProperty.PRE_UPDATE_VALUE. This should no longer cause a ClassCastException. */ + em = getOrCreateEntityManager(); em.getTransaction().begin(); entity = em.find(EntityWithLazyProperty.class, entity.getId()); entity.setUpdateLazyFieldInPreUpdate(true); entity.setSomeField("TEST2"); + assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); em.getTransaction().commit(); + assertTrue( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); + em.close(); + checkLazyField(entity, em, EntityWithLazyProperty.PRE_UPDATE_VALUE); /** @@ -305,22 +321,29 @@ public class CallbacksTest extends BaseEntityManagerFunctionalTestCase { * PreUpdate annotated callback method and also set the lazyData field directly to testArray1. When we reload we * should get EntityWithLazyProperty.PRE_UPDATE_VALUE. */ + em = getOrCreateEntityManager(); em.getTransaction().begin(); entity = em.find(EntityWithLazyProperty.class, entity.getId()); entity.setUpdateLazyFieldInPreUpdate(true); + assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); entity.setLazyData(testArray); + assertTrue( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); entity.setSomeField("TEST3"); em.getTransaction().commit(); - checkLazyField(entity, em, EntityWithLazyProperty.PRE_UPDATE_VALUE); - em.close(); + + checkLazyField( entity, em, EntityWithLazyProperty.PRE_UPDATE_VALUE); } private void checkLazyField(EntityWithLazyProperty entity, EntityManager em, byte[] expected) { // reload the entity and check the lazy value matches what we expect. + em = getOrCreateEntityManager(); em.getTransaction().begin(); entity = em.find(EntityWithLazyProperty.class, entity.getId()); - assertEquals(expected, entity.getLazyData()); + assertFalse( Hibernate.isPropertyInitialized( entity, "lazyData") ); + assertTrue( ArrayHelper.isEquals( expected, entity.getLazyData() ) ); + assertTrue( Hibernate.isPropertyInitialized( entity, "lazyData" ) ); em.getTransaction().commit(); + em.close(); } } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/EntityWithLazyProperty.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/EntityWithLazyProperty.java index f38af8b130..266bf28cdd 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/EntityWithLazyProperty.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/callbacks/EntityWithLazyProperty.java @@ -1,9 +1,17 @@ +/* + * 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 . + */ package org.hibernate.jpa.test.callbacks; import javax.persistence.*; /** * Test entity with a lazy property which requires build time instrumentation. + * + * @author Martin Ball */ @Entity public class EntityWithLazyProperty {