HHH-9985 - bytecode enhancement - add testcase, and for HHH-10017 as well

This commit is contained in:
barreiro 2015-08-05 09:12:37 +01:00
parent c622d39199
commit cff4cb4b7a
10 changed files with 476 additions and 19 deletions

View File

@ -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 ) );

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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" );
}

View File

@ -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();

View File

@ -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<Child> 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<Child> getChildren() {
return children;
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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;
}
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<String> languages;
}
}

View File

@ -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) {