From 4c900da6892cd0bc71cc89649eee8071a63906d7 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Wed, 29 Jun 2016 17:19:25 -0700 Subject: [PATCH] HHH-10865 - ManyToMany relation dropped from database when lazy loading is active (cherry picked from commit 8e8be9aeb44012b468659bddb22563d209d4b900) Conflicts: hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java hibernate-core/src/main/java/org/hibernate/tuple/entity/BytecodeEnhancementMetadataPojoImpl.java --- .../tuple/entity/AbstractEntityTuplizer.java | 9 +- .../bytecode/enhancement/EnhancerTest.java | 2 + .../enhancement/lazy/HHH_10708/Child.java | 10 ++ .../enhancement/lazy/HHH_10708/Parent.java | 10 ++ .../UnexpectedDeleteThreeTestTask.java | 152 ++++++++++++++++++ 5 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Child.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Parent.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/UnexpectedDeleteThreeTestTask.java diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java index 9682ee2901..acac92d79a 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java @@ -14,7 +14,9 @@ import java.util.Set; import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor; import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; +import org.hibernate.bytecode.spi.EntityInstrumentationMetadata; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.PersistenceContext; @@ -491,13 +493,16 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { @Override public Object[] getPropertyValues(Object entity) throws HibernateException { - boolean getAll = shouldGetAllProperties( entity ); final int span = entityMetamodel.getPropertySpan(); final Object[] result = new Object[span]; + final EntityInstrumentationMetadata enhancementMetadata = entityMetamodel.getInstrumentationMetadata(); + final FieldInterceptor interceptor = enhancementMetadata.isInstrumented() + ? enhancementMetadata.extractInterceptor( entity ) + : null; for ( int j = 0; j < span; j++ ) { NonIdentifierAttribute property = entityMetamodel.getProperties()[j]; - if ( getAll || !property.isLazy() ) { + if ( !property.isLazy() || interceptor == null || interceptor.isInitialized( property.getName() ) ) { result[j] = getters[j].get( entity ); } else { diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java index 4967daa1ab..f338e55ec4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTest.java @@ -24,6 +24,7 @@ import org.hibernate.test.bytecode.enhancement.join.HHH3949TestTask2; import org.hibernate.test.bytecode.enhancement.join.HHH3949TestTask3; import org.hibernate.test.bytecode.enhancement.join.HHH3949TestTask4; import org.hibernate.test.bytecode.enhancement.lazy.HHH_10708.UnexpectedDeleteOneTestTask; +import org.hibernate.test.bytecode.enhancement.lazy.HHH_10708.UnexpectedDeleteThreeTestTask; import org.hibernate.test.bytecode.enhancement.lazy.HHH_10708.UnexpectedDeleteTwoTestTask; import org.hibernate.test.bytecode.enhancement.lazy.LazyBasicFieldNotInitializedTestTask; import org.hibernate.test.bytecode.enhancement.lazy.LazyCollectionLoadingTestTask; @@ -106,6 +107,7 @@ public class EnhancerTest extends BaseUnitTestCase { public void testLazyUnexpectedDelete() { EnhancerTestUtils.runEnhancerTestTask( UnexpectedDeleteOneTestTask.class ); EnhancerTestUtils.runEnhancerTestTask( UnexpectedDeleteTwoTestTask.class ); + EnhancerTestUtils.runEnhancerTestTask( UnexpectedDeleteThreeTestTask.class ); } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Child.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Child.java new file mode 100644 index 0000000000..bbfde37091 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Child.java @@ -0,0 +1,10 @@ +/* + * 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.test.bytecode.enhancement.lazy.HHH_10708; + +public class Child { +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Parent.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Parent.java new file mode 100644 index 0000000000..27f48239ed --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/Parent.java @@ -0,0 +1,10 @@ +/* + * 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.test.bytecode.enhancement.lazy.HHH_10708; + +public class Parent { +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/UnexpectedDeleteThreeTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/UnexpectedDeleteThreeTestTask.java new file mode 100644 index 0000000000..f847f382ff --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/HHH_10708/UnexpectedDeleteThreeTestTask.java @@ -0,0 +1,152 @@ +/* + * 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.test.bytecode.enhancement.lazy.HHH_10708; + +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; +import org.junit.Assert; + +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class UnexpectedDeleteThreeTestTask extends AbstractEnhancerTestTask { + + @Override + public Class[] getAnnotatedClasses() { + return new Class[] { Parent.class, Child.class }; + } + + @Override + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + prepare( cfg ); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Child child = new Child(); + child.setId( 2L ); + s.save(child); + + Parent parent = new Parent(); + parent.setId( 1L ); + parent.setNames( Collections.singleton( "name" ) ); + + Set children = new HashSet(); + children.add(child); + parent.setChildren( children ); + + s.save( parent ); + + s.getTransaction().commit(); + s.clear(); + s.close(); + } + + @Override + public void execute() { + Session s = getFactory().openSession(); + s.beginTransaction(); + + Parent parent = s.get( Parent.class, 1L ); + Set children = parent.getChildren(); + if (children == null) { + children = new HashSet(); + parent.setChildren( children ); + } + Child child = new Child(); + child.setId( 1L ); + s.save(child); + children.add(child); + + // We need to leave at least one attribute unfetchd + //parent.getNames().size(); + s.save(parent); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + + Parent application = s.get( Parent.class, 1L ); + Assert.assertEquals( "Loaded Children collection has unexpected size", 2, application.getChildren().size() ); + + s.getTransaction().commit(); + s.close(); + } + + @Override + protected void cleanup() { + } + + // --- // + + @Entity public static class Child { + + private Long id; + + @Id + @Column(name = "id", unique = true, nullable = false) + public Long getId() { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + } + + @Entity public static class Parent { + + private Long id; + private Set names; + private Set children; + + @Id @Column(name = "id", unique = true, nullable = false) + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @ElementCollection + public Set getNames() { + return names; + } + + public void setNames(Set secrets) { + this.names = secrets; + } + + @ManyToMany(fetch = FetchType.LAZY, targetEntity = Child.class) + public Set getChildren() { + return children; + } + + public void setChildren(Set children) { + this.children = children; + } + + } + +} \ No newline at end of file