diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/DecompileUtils.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/DecompileUtils.java index 31a98502b6..5d616e122d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/DecompileUtils.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/DecompileUtils.java @@ -102,6 +102,8 @@ public abstract class DecompileUtils { assertTrue( methodNames.contains( EnhancerConstants.TRACKER_GET_NAME ) ); assertTrue( methodNames.contains( EnhancerConstants.TRACKER_CLEAR_NAME ) ); assertTrue( methodNames.contains( EnhancerConstants.TRACKER_HAS_CHANGED_NAME ) ); + assertTrue( methodNames.contains( EnhancerConstants.TRACKER_SUSPEND_NAME ) ); + assertTrue( methodNames.contains( EnhancerConstants.TRACKER_COLLECTION_GET_NAME ) ); } if ( interfaceNames.contains( CompositeTracker.class.getName() ) ) { assertTrue( fieldNames.contains( EnhancerConstants.TRACKER_COMPOSITE_FIELD_NAME ) ); 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 17460895a5..4727c4b9ca 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 @@ -23,6 +23,9 @@ import org.hibernate.test.bytecode.enhancement.join.HHH3949TestTask4; import org.hibernate.test.bytecode.enhancement.lazy.LazyBasicFieldNotInitializedTestTask; import org.hibernate.test.bytecode.enhancement.lazy.LazyLoadingIntegrationTestTask; import org.hibernate.test.bytecode.enhancement.lazy.LazyLoadingTestTask; +import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicFieldAccessTestTask; +import org.hibernate.test.bytecode.enhancement.lazy.basic.LazyBasicPropertyAccessTestTask; +import org.hibernate.test.bytecode.enhancement.merge.CompositeMergeTestTask; import org.junit.Test; /** @@ -51,8 +54,17 @@ public class EnhancerTest extends BaseUnitTestCase { public void testLazy() { EnhancerTestUtils.runEnhancerTestTask( LazyLoadingTestTask.class ); EnhancerTestUtils.runEnhancerTestTask( LazyLoadingIntegrationTestTask.class ); + + EnhancerTestUtils.runEnhancerTestTask( LazyBasicPropertyAccessTestTask.class ); + EnhancerTestUtils.runEnhancerTestTask( LazyBasicFieldAccessTestTask.class ); } + @Test + public void testMerge() { + EnhancerTestUtils.runEnhancerTestTask( CompositeMergeTestTask.class ); + } + + @Test public void testFieldAccess() { EnhancerTestUtils.runEnhancerTestTask( FieldAccessEnhancementTestTask.class ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java index 89e0a63cf8..ca97c4a786 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/EnhancerTestUtils.java @@ -9,13 +9,10 @@ package org.hibernate.test.bytecode.enhancement; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; import java.util.Arrays; import javassist.ClassPool; @@ -150,9 +147,12 @@ public abstract class EnhancerTestUtils extends BaseUnitTestCase { final byte[] enhanced = new Enhancer( enhancementContext ).enhance( name, original ); - Path debugOutput = Paths.get( workingDir + File.separator + name.replace( '.', '/' ) + ".class" ); - Files.createDirectories( debugOutput.getParent() ); - Files.write( debugOutput, enhanced, StandardOpenOption.CREATE ); + File f = new File( workingDir + File.separator + name.replace( ".", File.separator ) + ".class" ); + f.getParentFile().mkdirs(); + f.createNewFile(); + FileOutputStream out = new FileOutputStream( f ); + out.write( enhanced ); + out.close(); return defineClass( name, enhanced, 0, enhanced.length ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/dirty/DirtyTrackingTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/dirty/DirtyTrackingTestTask.java index 96d1586a4b..624726f17a 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/dirty/DirtyTrackingTestTask.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/dirty/DirtyTrackingTestTask.java @@ -30,19 +30,19 @@ public class DirtyTrackingTestTask extends AbstractEnhancerTestTask { SimpleEntity entity = new SimpleEntity(); // Basic single field - entity.getId(); + entity.getSomeNumber(); EnhancerTestUtils.checkDirtyTracking( entity ); - entity.setId( 1l ); - EnhancerTestUtils.checkDirtyTracking( entity, "id" ); + entity.setSomeNumber( 1l ); + EnhancerTestUtils.checkDirtyTracking( entity, "someNumber" ); EnhancerTestUtils.clearDirtyTracking( entity ); - entity.setId( entity.getId() ); + entity.setSomeNumber( entity.getSomeNumber() ); EnhancerTestUtils.checkDirtyTracking( entity ); - // Basic multi-field + // Basic multi-field (Id properties are not flagged as dirty) entity.setId( 2l ); entity.setActive( !entity.isActive() ); entity.setSomeNumber( 193L ); - EnhancerTestUtils.checkDirtyTracking( entity, "id", "active", "someNumber" ); + EnhancerTestUtils.checkDirtyTracking( entity, "active", "someNumber" ); EnhancerTestUtils.clearDirtyTracking( entity ); // Setting the same value should not make it dirty @@ -70,7 +70,7 @@ public class DirtyTrackingTestTask extends AbstractEnhancerTestTask { Address address = new Address(); entity.setAddress( address ); address.setCity( "Arendal" ); - EnhancerTestUtils.checkDirtyTracking( entity, "address", "address.city" ); + EnhancerTestUtils.checkDirtyTracking( entity, "address" ); EnhancerTestUtils.clearDirtyTracking( entity ); // make sure that new composite instances are cleared @@ -82,7 +82,7 @@ public class DirtyTrackingTestTask extends AbstractEnhancerTestTask { Country country = new Country(); address2.setCountry( country ); country.setName( "Norway" ); - EnhancerTestUtils.checkDirtyTracking( entity, "address", "address.country", "address.country.name" ); + EnhancerTestUtils.checkDirtyTracking( entity, "address", "address.country" ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/LazyLoadingIntegrationTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/LazyLoadingIntegrationTestTask.java index 5fe860ea03..7ea64c7906 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/LazyLoadingIntegrationTestTask.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/LazyLoadingIntegrationTestTask.java @@ -75,7 +75,7 @@ public class LazyLoadingIntegrationTestTask extends AbstractEnhancerTestTask { loadedChildren.remove( loadedChild ); loadedParent.setChildren( loadedChildren ); - EnhancerTestUtils.checkDirtyTracking( loadedParent ); + EnhancerTestUtils.checkDirtyTracking( loadedParent, "children" ); Assert.assertNull( loadedChild.parent ); s.getTransaction().commit(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/Parent.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/Parent.java index e2d374a695..fd8aadbd3d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/Parent.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/Parent.java @@ -22,13 +22,12 @@ import javax.persistence.OneToMany; @Entity public class Parent { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) Long id; - @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY) List children; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) public Long getId() { return id; } @@ -37,6 +36,7 @@ public class Parent { this.id = id; } + @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY) public List getChildren() { return children; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicFieldAccessTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicFieldAccessTestTask.java new file mode 100644 index 0000000000..2a90f941c3 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicFieldAccessTestTask.java @@ -0,0 +1,142 @@ +/* + * 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.basic; + + +import javax.persistence.Basic; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; +import org.hibernate.test.bytecode.enhancement.EnhancerTestUtils; +import org.junit.Assert; + +/** + * @author Gail Badner + */ +public class LazyBasicFieldAccessTestTask extends AbstractEnhancerTestTask { + + private Long entityId; + + public Class[] getAnnotatedClasses() { + return new Class[] {Entity.class}; + } + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Entity entity = new Entity(); + entity.setDescription( "desc" ); + s.persist( entity ); + entityId = entity.getId(); + + s.getTransaction().commit(); + s.clear(); + s.close(); + } + + public void execute() { + Session s = getFactory().openSession(); + s.beginTransaction(); + + Entity entity = s.get( Entity.class, entityId ); + + Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity ); + + Assert.assertEquals( "desc", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity.setDescription( "desc1" ); + s.update( entity ); + + //Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity, "description" ); + + Assert.assertEquals( "desc1", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity = s.get( Entity.class, entityId ); + Assert.assertEquals( "desc1", entity.getDescription() ); + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity.setDescription( "desc2" ); + entity = (Entity) s.merge( entity ); + + //Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity, "description" ); + + Assert.assertEquals( "desc2", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity = s.get( Entity.class, entityId ); + Assert.assertEquals( "desc2", entity.getDescription() ); + s.getTransaction().commit(); + s.close(); + } + + protected void cleanup() { + } + + @javax.persistence.Entity + public static class Entity { + private Long id; + + private String description; + + @Id + @GeneratedValue + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @Basic(fetch = FetchType.LAZY) + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } + + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicPropertyAccessTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicPropertyAccessTestTask.java new file mode 100644 index 0000000000..3715b376f2 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/lazy/basic/LazyBasicPropertyAccessTestTask.java @@ -0,0 +1,145 @@ +/* + * 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.basic; + + +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Basic; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; +import org.hibernate.test.bytecode.enhancement.EnhancerTestUtils; +import org.junit.Assert; + +/** + * @author Gail Badner + */ +public class LazyBasicPropertyAccessTestTask extends AbstractEnhancerTestTask { + + private Long entityId; + + public Class[] getAnnotatedClasses() { + return new Class[] {Entity.class}; + } + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + Session s = getFactory().openSession(); + s.beginTransaction(); + + Entity entity = new Entity(); + entity.setDescription( "desc" ); + s.persist( entity ); + entityId = entity.getId(); + + s.getTransaction().commit(); + s.clear(); + s.close(); + } + + public void execute() { + Session s = getFactory().openSession(); + s.beginTransaction(); + + Entity entity = s.get( Entity.class, entityId ); + + Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity ); + + Assert.assertEquals( "desc", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity.setDescription( "desc1" ); + s.update( entity ); + + // Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity, "description" ); + + Assert.assertEquals( "desc1", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity = s.get( Entity.class, entityId ); + Assert.assertEquals( "desc1", entity.getDescription() ); + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity.setDescription( "desc2" ); + entity = (Entity) s.merge( entity ); + + //Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); + EnhancerTestUtils.checkDirtyTracking( entity, "description" ); + + Assert.assertEquals( "desc2", entity.getDescription() ); + Assert.assertTrue( Hibernate.isPropertyInitialized( entity, "description" ) ); + + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + entity = s.get( Entity.class, entityId ); + Assert.assertEquals( "desc2", entity.getDescription() ); + s.getTransaction().commit(); + s.close(); + } + + protected void cleanup() { + } + + @javax.persistence.Entity + @Access(AccessType.FIELD ) + public static class Entity { + @Id + @GeneratedValue + private Long id; + + @Basic(fetch = FetchType.LAZY) + private String description; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } + + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/merge/CompositeMergeTestTask.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/merge/CompositeMergeTestTask.java new file mode 100644 index 0000000000..49a8d0430c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/merge/CompositeMergeTestTask.java @@ -0,0 +1,149 @@ +/* + * 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.merge; + +import java.util.Arrays; +import java.util.List; +import javax.persistence.Basic; +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.Session; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; + +import org.hibernate.test.bytecode.enhancement.AbstractEnhancerTestTask; +import org.hibernate.test.bytecode.enhancement.EnhancerTestUtils; +import org.junit.Assert; + +/** + * @author Luis Barreiro + */ +public class CompositeMergeTestTask extends AbstractEnhancerTestTask { + + private long entityId; + + public Class[] getAnnotatedClasses() { + return new Class[] { ParentEntity.class, Address.class, Country.class }; + } + + public void prepare() { + Configuration cfg = new Configuration(); + cfg.setProperty( Environment.ENABLE_LAZY_LOAD_NO_TRANS, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + super.prepare( cfg ); + + ParentEntity parent = new ParentEntity(); + parent.description = "desc"; + parent.address = new Address(); + parent.address.street = "Sesame street"; + parent.address.country = new Country(); + parent.address.country.name = "Suriname"; + parent.address.country.languages = Arrays.asList( "english", "spanish" ); + + parent.lazyField = new byte[100]; + + Session s = getFactory().openSession(); + s.beginTransaction(); + s.persist( parent ); + s.getTransaction().commit(); + s.close(); + + EnhancerTestUtils.checkDirtyTracking( parent ); + entityId = parent.id; + } + + public void execute() { + Session s = getFactory().openSession(); + s.beginTransaction(); + ParentEntity parent = s.get( ParentEntity.class, entityId ); + s.getTransaction().commit(); + s.close(); + + EnhancerTestUtils.checkDirtyTracking( parent ); + + parent.address.country.name = "Paraguai"; + + EnhancerTestUtils.checkDirtyTracking( parent, "address.country" ); + + s = getFactory().openSession(); + s.beginTransaction(); + ParentEntity mergedParent = (ParentEntity) s.merge( parent ); + EnhancerTestUtils.checkDirtyTracking( parent, "address.country" ); + EnhancerTestUtils.checkDirtyTracking( mergedParent, "address.country" ); + s.getTransaction().commit(); + s.close(); + + EnhancerTestUtils.checkDirtyTracking( parent, "address.country" ); + EnhancerTestUtils.checkDirtyTracking( mergedParent ); + + mergedParent.address.country.name = "Honduras"; + + EnhancerTestUtils.checkDirtyTracking( mergedParent, "address.country" ); + + s = getFactory().openSession(); + s.beginTransaction(); + s.saveOrUpdate( mergedParent ); + EnhancerTestUtils.checkDirtyTracking( mergedParent, "address.country" ); + s.getTransaction().commit(); + s.close(); + + s = getFactory().openSession(); + s.beginTransaction(); + parent = s.get( ParentEntity.class, entityId ); + s.getTransaction().commit(); + s.close(); + + Assert.assertEquals( "Honduras", parent.address.country.name ); + } + + protected void cleanup() { + } + + @Entity + private static class ParentEntity { + + @Id + @GeneratedValue + private long id; + + private String description; + + @Embedded + private Address address; + + @Basic(fetch = FetchType.LAZY) + private byte[] lazyField; + + } + + @Embeddable + private static class Address { + + private String street; + + @Embedded + private Country country; + + } + + @Embeddable + private static class Country { + + private String name; + + @ElementCollection + List languages; + + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/tracker/DirtyTrackerTest.java b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/tracker/DirtyTrackerTest.java index cbd64baece..f182d5501b 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/tracker/DirtyTrackerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/bytecode/enhancement/tracker/DirtyTrackerTest.java @@ -43,6 +43,9 @@ public class DirtyTrackerTest { tracker.add("another.bar"); assertTrue(tracker.get().length == 4); + tracker.suspend(true); + tracker.add("one more"); + assertTrue(tracker.get().length == 4); } @Test @@ -69,6 +72,10 @@ public class DirtyTrackerTest { // we the algorithm for this implementation relies on the fact that the array is kept sorted, so let's check it really is assertTrue(isSorted(tracker.get())); + + tracker.suspend(true); + tracker.add("one more"); + assertTrue(tracker.get().length == 4); } private boolean isSorted(String[] arr) {