HHH-11820 - Simplify dirty tracking on entities without collections [javassist]

This commit is contained in:
barreiro 2017-07-25 02:44:41 +01:00 committed by Gail Badner
parent e99eb2b7a2
commit c392d20dec
2 changed files with 143 additions and 47 deletions

View File

@ -21,6 +21,7 @@ import javassist.Modifier;
import javassist.NotFoundException;
import org.hibernate.bytecode.enhance.internal.tracker.DirtyTracker;
import org.hibernate.bytecode.enhance.internal.tracker.NoopCollectionTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleCollectionTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
import org.hibernate.bytecode.enhance.spi.CollectionTracker;
@ -120,16 +121,84 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
loadCtClassFromClass( DirtyTracker.class ),
EnhancerConstants.TRACKER_FIELD_NAME
);
if ( collectCollectionFields( managedCtClass ).isEmpty() ) {
createDirtyTrackerMethodsWithoutCollections( managedCtClass );
}
else {
FieldWriter.addField(
managedCtClass,
loadCtClassFromClass( CollectionTracker.class ),
EnhancerConstants.TRACKER_COLLECTION_NAME
);
createDirtyTrackerMethods( managedCtClass );
createDirtyTrackerMethodsWithCollections( managedCtClass );
}
}
private void createDirtyTrackerMethods(CtClass managedCtClass) {
private void createDirtyTrackerMethodsWithoutCollections(CtClass managedCtClass) {
try {
MethodWriter.write(
managedCtClass,
"public void %1$s(String name) {%n" +
" if (%2$s == null) { %2$s = new %3$s(); }%n" +
" %2$s.add(name);%n" +
"}",
EnhancerConstants.TRACKER_CHANGER_NAME,
EnhancerConstants.TRACKER_FIELD_NAME,
DIRTY_TRACKER_IMPL
);
MethodWriter.write(
managedCtClass,
"public String[] %1$s() {%n" +
" return (%2$s == null) ? new String[0] : %2$s.get();%n" +
"}",
EnhancerConstants.TRACKER_GET_NAME,
EnhancerConstants.TRACKER_FIELD_NAME
);
MethodWriter.write(
managedCtClass,
"public boolean %1$s() {%n" +
" return (%2$s != null && !%2$s.isEmpty());%n" +
"}",
EnhancerConstants.TRACKER_HAS_CHANGED_NAME,
EnhancerConstants.TRACKER_FIELD_NAME
);
MethodWriter.write(
managedCtClass,
"public void %1$s() {%n" +
" if (%2$s != null) { %2$s.clear(); }%n" +
"}",
EnhancerConstants.TRACKER_CLEAR_NAME,
EnhancerConstants.TRACKER_FIELD_NAME
);
MethodWriter.write(
managedCtClass,
"public void %1$s(boolean f) {%n" +
" if (%2$s == null) %2$s = new %3$s();%n %2$s.suspend(f);%n" +
"}",
EnhancerConstants.TRACKER_SUSPEND_NAME,
EnhancerConstants.TRACKER_FIELD_NAME ,
DIRTY_TRACKER_IMPL
);
MethodWriter.write(
managedCtClass,
"public %s %s() { return %s.INSTANCE; }",
CollectionTracker.class.getName(),
EnhancerConstants.TRACKER_COLLECTION_GET_NAME,
NoopCollectionTracker.class.getName()
);
}
catch (CannotCompileException cce) {
cce.printStackTrace();
}
}
private void createDirtyTrackerMethodsWithCollections(CtClass managedCtClass) {
try {
MethodWriter.write(
managedCtClass,
@ -216,7 +285,7 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
continue;
}
if ( enhancementContext.isPersistentField( ctField ) ) {
if ( enhancementContext.isPersistentField( ctField ) && !enhancementContext.isMappedCollection( ctField ) ) {
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
collectionList.add( ctField );
@ -246,13 +315,15 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
List<CtField> collectionList = new ArrayList<CtField>();
for ( CtField ctField : managedCtSuperclass.getDeclaredFields() ) {
if ( !Modifier.isStatic( ctField.getModifiers() ) && enhancementContext.isPersistentField( ctField ) ) {
if ( !Modifier.isStatic( ctField.getModifiers() ) ) {
if ( enhancementContext.isPersistentField( ctField ) && !enhancementContext.isMappedCollection( ctField ) ) {
if ( PersistentAttributesHelper.isAssignable( ctField, Collection.class.getName() ) ||
PersistentAttributesHelper.isAssignable( ctField, Map.class.getName() ) ) {
collectionList.add( ctField );
}
}
}
}
collectionList.addAll( collectInheritCollectionFields( managedCtSuperclass ) );
return collectionList;
}
@ -275,7 +346,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
);
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append(
String.format(
" // collection field [%1$s]%n" +
@ -286,7 +356,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
)
);
}
}
body.append( " return false;%n}" );
MethodWriter.write( managedCtClass, body.toString() );
@ -311,7 +380,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
);
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append(
String.format(
" // Collection field [%1$s]%n" +
@ -322,7 +390,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
)
);
}
}
body.append( "}" );
MethodWriter.write( managedCtClass, body.toString() );
@ -359,7 +426,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
}
for ( CtField ctField : collectCollectionFields( managedCtClass ) ) {
if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append(
String.format(
" // collection field [%1$s]%n" +
@ -372,7 +438,6 @@ public class EntityEnhancer extends PersistentAttributesEnhancer {
)
);
}
}
body.append( "}" );
MethodWriter.write( managedCtClass, body.toString() );

View File

@ -0,0 +1,31 @@
/*
* 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.bytecode.enhance.internal.tracker;
import org.hibernate.bytecode.enhance.spi.CollectionTracker;
import java.util.Arrays;
/**
* small low memory class to keep track of the number of elements in a collection
*
* @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
*/
public final class NoopCollectionTracker implements CollectionTracker {
public static final CollectionTracker INSTANCE = new NoopCollectionTracker();
@Override
public void add(String name, int size) {
}
@Override
public int getSize(String name) {
return -1;
}
}