HHH-9806 Backport fix for bytecode enhancement dirty tracking not working when PersistentAttributeInterceptor is not injected

This commit is contained in:
barreiro 2015-05-21 16:28:37 +01:00
parent d9495474ef
commit bc382dde74
2 changed files with 39 additions and 46 deletions

View File

@ -23,20 +23,6 @@
*/
package org.hibernate.bytecode.enhance.spi;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
@ -58,7 +44,6 @@ import javassist.bytecode.SignatureAttribute;
import javassist.bytecode.StackMapTable;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.stackmap.MapMaker;
import org.hibernate.HibernateException;
import org.hibernate.bytecode.enhance.EnhancementException;
import org.hibernate.engine.spi.EntityEntry;
@ -70,6 +55,20 @@ import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
/**
* Class responsible for performing enhancement.
*
@ -660,7 +659,7 @@ public class Enhancer {
private void createCollectionDirtyCheckMethod(CtClass managedCtClass) throws CannotCompileException {
StringBuilder builder = new StringBuilder( "private boolean " )
.append( EnhancerConstants.TRACKER_COLLECTION_CHANGED_NAME )
.append( "() { if ($$_hibernate_getInterceptor() == null || " )
.append( "() { if (" )
.append( EnhancerConstants.TRACKER_COLLECTION_NAME )
.append( " == null) return false; " );
@ -1157,10 +1156,9 @@ public class Enhancer {
private String entityMethodBody(CtField currentValue) {
StringBuilder inlineBuilder = new StringBuilder();
try {
inlineBuilder.append( "if ( $$_hibernate_getInterceptor() != null " );
//primitives || enums
if ( currentValue.getType().isPrimitive() || currentValue.getType().isEnum() ) {
inlineBuilder.append( "&& " ).append( currentValue.getName() ).append( " != $1)" );
inlineBuilder.append( "if(" ).append( currentValue.getName() ).append( " != $1)" );
}
//simple data types
else if ( currentValue.getType().getName().startsWith( "java.lang" )
@ -1169,11 +1167,11 @@ public class Enhancer {
|| currentValue.getType().getName().startsWith( "java.sql.Date" )
|| currentValue.getType().getName().startsWith( "java.util.Date" )
|| currentValue.getType().getName().startsWith( "java.util.Calendar" ) ) {
inlineBuilder.append( "&& ((" )
inlineBuilder.append( "if(" )
.append( currentValue.getName() )
.append( " == null) || (!" )
.append( " == null || !" )
.append( currentValue.getName() )
.append( ".equals( $1))))" );
.append( ".equals( $1))" );
}
//all other objects
else {
@ -1192,11 +1190,11 @@ public class Enhancer {
}
//todo: for now just call equals, should probably do something else here
inlineBuilder.append( "&& ((" )
inlineBuilder.append( "if(" )
.append( currentValue.getName() )
.append( " == null) || (!" )
.append( " == null || !" )
.append( currentValue.getName() )
.append( ".equals( $1))))" );
.append( ".equals( $1))" );
}
inlineBuilder.append( EnhancerConstants.TRACKER_CHANGER_NAME + "(\"" )

View File

@ -23,21 +23,10 @@
*/
package org.hibernate.test.bytecode.enhancement;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.LoaderClassPath;
import org.hibernate.EntityMode;
import org.hibernate.LockMode;
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.Enhancer;
@ -46,14 +35,20 @@ import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.ManagedEntity;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.Status;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import javax.persistence.ElementCollection;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertEquals;
@ -186,14 +181,14 @@ public class EnhancerTest extends BaseUnitTestCase {
assertSame( entityInstance, nextGetter.invoke( entityInstance ) );
// add an attribute interceptor...
Method interceptorGetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_GETTER_NAME );
Method interceptorSetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_SETTER_NAME, PersistentAttributeInterceptor.class );
assertNull( interceptorGetter.invoke( entityInstance ) );
entityClass.getMethod( "getId" ).invoke( entityInstance );
interceptorSetter.invoke( entityInstance, new LocalPersistentAttributeInterceptor() );
assertNotNull(interceptorGetter.invoke(entityInstance));
// Method interceptorGetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_GETTER_NAME );
// Method interceptorSetter = entityClass.getMethod( EnhancerConstants.INTERCEPTOR_SETTER_NAME, PersistentAttributeInterceptor.class );
//
// assertNull( interceptorGetter.invoke( entityInstance ) );
// entityClass.getMethod( "getId" ).invoke( entityInstance );
//
// interceptorSetter.invoke( entityInstance, new LocalPersistentAttributeInterceptor() );
// assertNotNull(interceptorGetter.invoke(entityInstance));
// dirty checking is unfortunately just printlns for now... just verify the test output
entityClass.getMethod( "getId" ).invoke( entityInstance );