HHH-13097 Cache the annotations resolution

This commit is contained in:
Guillaume Smet 2018-11-13 16:08:50 +01:00 committed by Sanne Grinovero
parent d125349c07
commit 4ec71218e9
10 changed files with 203 additions and 166 deletions

View File

@ -17,6 +17,7 @@ import javax.persistence.ManyToOne;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancementException; import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
@ -43,7 +44,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
static Implementation wrap( static Implementation wrap(
TypeDescription managedCtClass, TypeDescription managedCtClass,
ByteBuddyEnhancementContext enhancementContext, ByteBuddyEnhancementContext enhancementContext,
FieldDescription persistentField, AnnotatedFieldDescription persistentField,
Implementation implementation) { Implementation implementation) {
if ( !enhancementContext.doBiDirectionalAssociationManagement( persistentField ) ) { if ( !enhancementContext.doBiDirectionalAssociationManagement( persistentField ) ) {
return implementation; return implementation;
@ -69,17 +70,17 @@ final class BiDirectionalAssociationHandler implements Implementation {
.getType() .getType()
.asErasure(); .asErasure();
if ( EnhancerImpl.isAnnotationPresent( persistentField, OneToOne.class ) ) { if ( persistentField.hasAnnotation( OneToOne.class ) ) {
implementation = Advice.withCustomMapping() implementation = Advice.withCustomMapping()
.bind( CodeTemplates.FieldValue.class, persistentField ) .bind( CodeTemplates.FieldValue.class, persistentField.getFieldDescription() )
.bind( CodeTemplates.MappedBy.class, mappedBy ) .bind( CodeTemplates.MappedBy.class, mappedBy )
.to( CodeTemplates.OneToOneHandler.class ) .to( CodeTemplates.OneToOneHandler.class )
.wrap( implementation ); .wrap( implementation );
} }
if ( EnhancerImpl.isAnnotationPresent( persistentField, OneToMany.class ) ) { if ( persistentField.hasAnnotation( OneToMany.class ) ) {
implementation = Advice.withCustomMapping() implementation = Advice.withCustomMapping()
.bind( CodeTemplates.FieldValue.class, persistentField ) .bind( CodeTemplates.FieldValue.class, persistentField.getFieldDescription() )
.bind( CodeTemplates.MappedBy.class, mappedBy ) .bind( CodeTemplates.MappedBy.class, mappedBy )
.to( persistentField.getType().asErasure().isAssignableTo( Map.class ) .to( persistentField.getType().asErasure().isAssignableTo( Map.class )
? CodeTemplates.OneToManyOnMapHandler.class ? CodeTemplates.OneToManyOnMapHandler.class
@ -87,15 +88,15 @@ final class BiDirectionalAssociationHandler implements Implementation {
.wrap( implementation ); .wrap( implementation );
} }
if ( EnhancerImpl.isAnnotationPresent( persistentField, ManyToOne.class ) ) { if ( persistentField.hasAnnotation( ManyToOne.class ) ) {
implementation = Advice.withCustomMapping() implementation = Advice.withCustomMapping()
.bind( CodeTemplates.FieldValue.class, persistentField ) .bind( CodeTemplates.FieldValue.class, persistentField.getFieldDescription() )
.bind( CodeTemplates.MappedBy.class, mappedBy ) .bind( CodeTemplates.MappedBy.class, mappedBy )
.to( CodeTemplates.ManyToOneHandler.class ) .to( CodeTemplates.ManyToOneHandler.class )
.wrap( implementation ); .wrap( implementation );
} }
if ( EnhancerImpl.isAnnotationPresent( persistentField, ManyToMany.class ) ) { if ( persistentField.hasAnnotation( ManyToMany.class ) ) {
if ( persistentField.getType().asErasure().isAssignableTo( Map.class ) || targetType.isAssignableTo( Map.class ) ) { if ( persistentField.getType().asErasure().isAssignableTo( Map.class ) || targetType.isAssignableTo( Map.class ) ) {
log.infof( log.infof(
@ -107,7 +108,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
} }
implementation = Advice.withCustomMapping() implementation = Advice.withCustomMapping()
.bind( CodeTemplates.FieldValue.class, persistentField ) .bind( CodeTemplates.FieldValue.class, persistentField.getFieldDescription() )
.bind( CodeTemplates.MappedBy.class, mappedBy ) .bind( CodeTemplates.MappedBy.class, mappedBy )
.to( CodeTemplates.ManyToManyHandler.class ) .to( CodeTemplates.ManyToManyHandler.class )
.wrap( implementation ); .wrap( implementation );
@ -116,12 +117,12 @@ final class BiDirectionalAssociationHandler implements Implementation {
return new BiDirectionalAssociationHandler( implementation, targetEntity, targetType, mappedBy ); return new BiDirectionalAssociationHandler( implementation, targetEntity, targetType, mappedBy );
} }
public static TypeDescription getTargetEntityClass(TypeDescription managedCtClass, FieldDescription persistentField) { public static TypeDescription getTargetEntityClass(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
try { try {
AnnotationDescription.Loadable<OneToOne> oto = EnhancerImpl.getAnnotation( persistentField, OneToOne.class ); AnnotationDescription.Loadable<OneToOne> oto = persistentField.getAnnotation( OneToOne.class );
AnnotationDescription.Loadable<OneToMany> otm = EnhancerImpl.getAnnotation( persistentField, OneToMany.class ); AnnotationDescription.Loadable<OneToMany> otm = persistentField.getAnnotation( OneToMany.class );
AnnotationDescription.Loadable<ManyToOne> mto = EnhancerImpl.getAnnotation( persistentField, ManyToOne.class ); AnnotationDescription.Loadable<ManyToOne> mto = persistentField.getAnnotation( ManyToOne.class );
AnnotationDescription.Loadable<ManyToMany> mtm = EnhancerImpl.getAnnotation( persistentField, ManyToMany.class ); AnnotationDescription.Loadable<ManyToMany> mtm = persistentField.getAnnotation( ManyToMany.class );
if ( oto == null && otm == null && mto == null && mtm == null ) { if ( oto == null && otm == null && mto == null && mtm == null ) {
return null; return null;
@ -159,7 +160,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
return entityType( target( persistentField ) ); return entityType( target( persistentField ) );
} }
private static TypeDescription.Generic target(FieldDescription persistentField) { private static TypeDescription.Generic target(AnnotatedFieldDescription persistentField) {
AnnotationDescription.Loadable<Access> access = persistentField.getDeclaringType().asErasure().getDeclaredAnnotations().ofType( Access.class ); AnnotationDescription.Loadable<Access> access = persistentField.getDeclaringType().asErasure().getDeclaredAnnotations().ofType( Access.class );
if ( access != null && access.loadSilent().value() == AccessType.FIELD ) { if ( access != null && access.loadSilent().value() == AccessType.FIELD ) {
return persistentField.getType(); return persistentField.getType();
@ -175,7 +176,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
} }
} }
private static String getMappedBy(FieldDescription target, TypeDescription targetEntity, ByteBuddyEnhancementContext context) { private static String getMappedBy(AnnotatedFieldDescription target, TypeDescription targetEntity, ByteBuddyEnhancementContext context) {
String mappedBy = getMappedByNotManyToMany( target ); String mappedBy = getMappedByNotManyToMany( target );
if ( mappedBy == null || mappedBy.isEmpty() ) { if ( mappedBy == null || mappedBy.isEmpty() ) {
return getMappedByManyToMany( target, targetEntity, context ); return getMappedByManyToMany( target, targetEntity, context );
@ -185,19 +186,19 @@ final class BiDirectionalAssociationHandler implements Implementation {
} }
} }
private static String getMappedByNotManyToMany(FieldDescription target) { private static String getMappedByNotManyToMany(AnnotatedFieldDescription target) {
try { try {
AnnotationDescription.Loadable<OneToOne> oto = EnhancerImpl.getAnnotation( target, OneToOne.class ); AnnotationDescription.Loadable<OneToOne> oto = target.getAnnotation( OneToOne.class );
if ( oto != null ) { if ( oto != null ) {
return oto.getValue( new MethodDescription.ForLoadedMethod( OneToOne.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class ); return oto.getValue( new MethodDescription.ForLoadedMethod( OneToOne.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class );
} }
AnnotationDescription.Loadable<OneToMany> otm = EnhancerImpl.getAnnotation( target, OneToMany.class ); AnnotationDescription.Loadable<OneToMany> otm = target.getAnnotation( OneToMany.class );
if ( otm != null ) { if ( otm != null ) {
return otm.getValue( new MethodDescription.ForLoadedMethod( OneToMany.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class ); return otm.getValue( new MethodDescription.ForLoadedMethod( OneToMany.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class );
} }
AnnotationDescription.Loadable<ManyToMany> mtm = EnhancerImpl.getAnnotation( target, ManyToMany.class ); AnnotationDescription.Loadable<ManyToMany> mtm = target.getAnnotation( ManyToMany.class );
if ( mtm != null ) { if ( mtm != null ) {
return mtm.getValue( new MethodDescription.ForLoadedMethod( ManyToMany.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class ); return mtm.getValue( new MethodDescription.ForLoadedMethod( ManyToMany.class.getDeclaredMethod( "mappedBy" ) ) ).resolve( String.class );
} }
@ -208,11 +209,12 @@ final class BiDirectionalAssociationHandler implements Implementation {
return null; return null;
} }
private static String getMappedByManyToMany(FieldDescription target, TypeDescription targetEntity, ByteBuddyEnhancementContext context) { private static String getMappedByManyToMany(AnnotatedFieldDescription target, TypeDescription targetEntity, ByteBuddyEnhancementContext context) {
for ( FieldDescription f : targetEntity.getDeclaredFields() ) { for ( FieldDescription f : targetEntity.getDeclaredFields() ) {
if ( context.isPersistentField( f ) AnnotatedFieldDescription annotatedF = new AnnotatedFieldDescription( f );
&& target.getName().equals( getMappedByNotManyToMany( f ) ) if ( context.isPersistentField( annotatedF )
&& target.getDeclaringType().asErasure().isAssignableTo( entityType( f.getType() ) ) ) { && target.getName().equals( getMappedByNotManyToMany( annotatedF ) )
&& target.getDeclaringType().asErasure().isAssignableTo( entityType( annotatedF.getType() ) ) ) {
log.debugf( log.debugf(
"mappedBy association for field [%s#%s] is [%s#%s]", "mappedBy association for field [%s#%s] is [%s#%s]",
target.getDeclaringType().asErasure().getName(), target.getDeclaringType().asErasure().getName(),

View File

@ -6,10 +6,9 @@
*/ */
package org.hibernate.bytecode.enhance.internal.bytebuddy; package org.hibernate.bytecode.enhance.internal.bytebuddy;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
class ByteBuddyEnhancementContext { class ByteBuddyEnhancementContext {
@ -36,10 +35,6 @@ class ByteBuddyEnhancementContext {
return enhancementContext.isMappedSuperclassClass( new UnloadedTypeDescription( classDescriptor ) ); return enhancementContext.isMappedSuperclassClass( new UnloadedTypeDescription( classDescriptor ) );
} }
public boolean doBiDirectionalAssociationManagement(FieldDescription field) {
return enhancementContext.doBiDirectionalAssociationManagement( new UnloadedFieldDescription( field ) );
}
public boolean doDirtyCheckingInline(TypeDescription classDescriptor) { public boolean doDirtyCheckingInline(TypeDescription classDescriptor) {
return enhancementContext.doDirtyCheckingInline( new UnloadedTypeDescription( classDescriptor ) ); return enhancementContext.doDirtyCheckingInline( new UnloadedTypeDescription( classDescriptor ) );
} }
@ -52,28 +47,23 @@ class ByteBuddyEnhancementContext {
return enhancementContext.hasLazyLoadableAttributes( new UnloadedTypeDescription( classDescriptor ) ); return enhancementContext.hasLazyLoadableAttributes( new UnloadedTypeDescription( classDescriptor ) );
} }
public boolean isPersistentField(FieldDescription ctField) { public boolean isPersistentField(AnnotatedFieldDescription field) {
return enhancementContext.isPersistentField( new UnloadedFieldDescription( ctField ) ); return enhancementContext.isPersistentField( field );
} }
public FieldDescription[] order(FieldDescription[] persistentFields) { public AnnotatedFieldDescription[] order(AnnotatedFieldDescription[] persistentFields) {
UnloadedField[] unloadedFields = new UnloadedField[persistentFields.length]; return (AnnotatedFieldDescription[]) enhancementContext.order( persistentFields );
for ( int i = 0; i < unloadedFields.length; i++ ) {
unloadedFields[i] = new UnloadedFieldDescription( persistentFields[i] );
}
UnloadedField[] ordered = enhancementContext.order( unloadedFields );
FieldDescription[] orderedFields = new FieldDescription[persistentFields.length];
for ( int i = 0; i < orderedFields.length; i++ ) {
orderedFields[i] = ( (UnloadedFieldDescription) ordered[i] ).fieldDescription;
}
return orderedFields;
} }
public boolean isLazyLoadable(FieldDescription field) { public boolean isLazyLoadable(AnnotatedFieldDescription field) {
return enhancementContext.isLazyLoadable( new UnloadedFieldDescription( field ) ); return enhancementContext.isLazyLoadable( field );
} }
public boolean isMappedCollection(FieldDescription field) { public boolean isMappedCollection(AnnotatedFieldDescription field) {
return enhancementContext.isMappedCollection( new UnloadedFieldDescription( field ) ); return enhancementContext.isMappedCollection( field );
}
public boolean doBiDirectionalAssociationManagement(AnnotatedFieldDescription field) {
return enhancementContext.doBiDirectionalAssociationManagement( field );
} }
} }

View File

@ -28,6 +28,7 @@ import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementException; import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.Enhancer;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState; import org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState;
import org.hibernate.engine.spi.CompositeOwner; import org.hibernate.engine.spi.CompositeOwner;
@ -46,13 +47,16 @@ import org.hibernate.internal.CoreMessageLogger;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.annotation.AnnotationDescription; import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldDescription.InDefinedShape;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.MethodList; import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.modifier.FieldPersistence; import net.bytebuddy.description.modifier.FieldPersistence;
import net.bytebuddy.description.modifier.Visibility; import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDefinition; import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeDescription.Generic;
import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.scaffold.MethodGraph; import net.bytebuddy.dynamic.scaffold.MethodGraph;
@ -60,6 +64,7 @@ import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.FixedValue; import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.StubMethod; import net.bytebuddy.implementation.StubMethod;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.pool.TypePool; import net.bytebuddy.pool.TypePool;
public class EnhancerImpl implements Enhancer { public class EnhancerImpl implements Enhancer {
@ -182,7 +187,9 @@ public class EnhancerImpl implements Enhancer {
builder = addInterceptorHandling( builder, managedCtClass ); builder = addInterceptorHandling( builder, managedCtClass );
if ( enhancementContext.doDirtyCheckingInline( managedCtClass ) ) { if ( enhancementContext.doDirtyCheckingInline( managedCtClass ) ) {
if ( collectCollectionFields( managedCtClass ).isEmpty() ) { List<AnnotatedFieldDescription> collectionFields = collectCollectionFields( managedCtClass );
if ( collectionFields.isEmpty() ) {
builder = builder.implement( SelfDirtinessTracker.class ) builder = builder.implement( SelfDirtinessTracker.class )
.defineField( EnhancerConstants.TRACKER_FIELD_NAME, DirtyTracker.class, FieldPersistence.TRANSIENT, Visibility.PRIVATE ) .defineField( EnhancerConstants.TRACKER_FIELD_NAME, DirtyTracker.class, FieldPersistence.TRANSIENT, Visibility.PRIVATE )
.annotateField( AnnotationDescription.Builder.ofType( Transient.class ).build() ) .annotateField( AnnotationDescription.Builder.ofType( Transient.class ).build() )
@ -223,38 +230,38 @@ public class EnhancerImpl implements Enhancer {
.intercept( FieldAccessor.ofField( EnhancerConstants.TRACKER_COLLECTION_NAME ) ); .intercept( FieldAccessor.ofField( EnhancerConstants.TRACKER_COLLECTION_NAME ) );
Implementation isDirty = StubMethod.INSTANCE, getDirtyNames = StubMethod.INSTANCE, clearDirtyNames = StubMethod.INSTANCE; Implementation isDirty = StubMethod.INSTANCE, getDirtyNames = StubMethod.INSTANCE, clearDirtyNames = StubMethod.INSTANCE;
for ( FieldDescription collectionField : collectCollectionFields( managedCtClass ) ) { for ( AnnotatedFieldDescription collectionField : collectionFields ) {
if ( collectionField.getType().asErasure().isAssignableTo( Map.class ) ) { if ( collectionField.getType().asErasure().isAssignableTo( Map.class ) ) {
isDirty = Advice.withCustomMapping() isDirty = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.MapAreCollectionFieldsDirty.class, adviceLocator ) .to( CodeTemplates.MapAreCollectionFieldsDirty.class, adviceLocator )
.wrap( isDirty ); .wrap( isDirty );
getDirtyNames = Advice.withCustomMapping() getDirtyNames = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.MapGetCollectionFieldDirtyNames.class, adviceLocator ) .to( CodeTemplates.MapGetCollectionFieldDirtyNames.class, adviceLocator )
.wrap( getDirtyNames ); .wrap( getDirtyNames );
clearDirtyNames = Advice.withCustomMapping() clearDirtyNames = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.MapGetCollectionClearDirtyNames.class, adviceLocator ) .to( CodeTemplates.MapGetCollectionClearDirtyNames.class, adviceLocator )
.wrap( clearDirtyNames ); .wrap( clearDirtyNames );
} }
else { else {
isDirty = Advice.withCustomMapping() isDirty = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.CollectionAreCollectionFieldsDirty.class, adviceLocator ) .to( CodeTemplates.CollectionAreCollectionFieldsDirty.class, adviceLocator )
.wrap( isDirty ); .wrap( isDirty );
getDirtyNames = Advice.withCustomMapping() getDirtyNames = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.CollectionGetCollectionFieldDirtyNames.class, adviceLocator ) .to( CodeTemplates.CollectionGetCollectionFieldDirtyNames.class, adviceLocator )
.wrap( getDirtyNames ); .wrap( getDirtyNames );
clearDirtyNames = Advice.withCustomMapping() clearDirtyNames = Advice.withCustomMapping()
.bind( CodeTemplates.FieldName.class, collectionField.getName() ) .bind( CodeTemplates.FieldName.class, collectionField.getName() )
.bind( CodeTemplates.FieldValue.class, collectionField ) .bind( CodeTemplates.FieldValue.class, collectionField.getFieldDescription() )
.to( CodeTemplates.CollectionGetCollectionClearDirtyNames.class, adviceLocator ) .to( CodeTemplates.CollectionGetCollectionClearDirtyNames.class, adviceLocator )
.wrap( clearDirtyNames ); .wrap( clearDirtyNames );
} }
@ -375,17 +382,18 @@ public class EnhancerImpl implements Enhancer {
.intercept( FieldAccessor.ofField( fieldName ) ); .intercept( FieldAccessor.ofField( fieldName ) );
} }
private List<FieldDescription> collectCollectionFields(TypeDescription managedCtClass) { private List<AnnotatedFieldDescription> collectCollectionFields(TypeDescription managedCtClass) {
List<FieldDescription> collectionList = new ArrayList<>(); List<AnnotatedFieldDescription> collectionList = new ArrayList<>();
for ( FieldDescription ctField : managedCtClass.getDeclaredFields() ) { for ( FieldDescription ctField : managedCtClass.getDeclaredFields() ) {
// skip static fields and skip fields added by enhancement // skip static fields and skip fields added by enhancement
if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) { if ( Modifier.isStatic( ctField.getModifiers() ) || ctField.getName().startsWith( "$$_hibernate_" ) ) {
continue; continue;
} }
if ( enhancementContext.isPersistentField( ctField ) && !enhancementContext.isMappedCollection( ctField ) ) { AnnotatedFieldDescription annotatedField = new AnnotatedFieldDescription( ctField );
if ( enhancementContext.isPersistentField( annotatedField ) && !enhancementContext.isMappedCollection( annotatedField ) ) {
if ( ctField.getType().asErasure().isAssignableTo( Collection.class ) || ctField.getType().asErasure().isAssignableTo( Map.class ) ) { if ( ctField.getType().asErasure().isAssignableTo( Collection.class ) || ctField.getType().asErasure().isAssignableTo( Map.class ) ) {
collectionList.add( ctField ); collectionList.add( annotatedField );
} }
} }
} }
@ -399,7 +407,7 @@ public class EnhancerImpl implements Enhancer {
return collectionList; return collectionList;
} }
private Collection<FieldDescription> collectInheritCollectionFields(TypeDefinition managedCtClass) { private Collection<AnnotatedFieldDescription> collectInheritCollectionFields(TypeDefinition managedCtClass) {
TypeDefinition managedCtSuperclass = managedCtClass.getSuperClass(); TypeDefinition managedCtSuperclass = managedCtClass.getSuperClass();
if ( managedCtSuperclass == null || managedCtSuperclass.represents( Object.class ) ) { if ( managedCtSuperclass == null || managedCtSuperclass.represents( Object.class ) ) {
return Collections.emptyList(); return Collections.emptyList();
@ -408,13 +416,14 @@ public class EnhancerImpl implements Enhancer {
if ( !enhancementContext.isMappedSuperclassClass( managedCtSuperclass.asErasure() ) ) { if ( !enhancementContext.isMappedSuperclassClass( managedCtSuperclass.asErasure() ) ) {
return collectInheritCollectionFields( managedCtSuperclass.asErasure() ); return collectInheritCollectionFields( managedCtSuperclass.asErasure() );
} }
List<FieldDescription> collectionList = new ArrayList<FieldDescription>(); List<AnnotatedFieldDescription> collectionList = new ArrayList<>();
for ( FieldDescription ctField : managedCtSuperclass.getDeclaredFields() ) { for ( FieldDescription ctField : managedCtSuperclass.getDeclaredFields() ) {
if ( !Modifier.isStatic( ctField.getModifiers() ) ) { if ( !Modifier.isStatic( ctField.getModifiers() ) ) {
if ( enhancementContext.isPersistentField( ctField ) && !enhancementContext.isMappedCollection( ctField ) ) { AnnotatedFieldDescription annotatedField = new AnnotatedFieldDescription( ctField );
if ( enhancementContext.isPersistentField( annotatedField ) && !enhancementContext.isMappedCollection( annotatedField ) ) {
if ( ctField.getType().asErasure().isAssignableTo( Collection.class ) || ctField.getType().asErasure().isAssignableTo( Map.class ) ) { if ( ctField.getType().asErasure().isAssignableTo( Collection.class ) || ctField.getType().asErasure().isAssignableTo( Map.class ) ) {
collectionList.add( ctField ); collectionList.add( annotatedField );
} }
} }
} }
@ -427,41 +436,15 @@ public class EnhancerImpl implements Enhancer {
return Character.toUpperCase( value.charAt( 0 ) ) + value.substring( 1 ); return Character.toUpperCase( value.charAt( 0 ) ) + value.substring( 1 );
} }
static boolean isAnnotationPresent(FieldDescription fieldDescription, Class<? extends Annotation> type) { static MethodDescription getterOf(AnnotatedFieldDescription persistentField) {
return getAnnotation( fieldDescription, type ) != null; return getterOf( persistentField.fieldDescription );
}
static <T extends Annotation> AnnotationDescription.Loadable<T> getAnnotation(FieldDescription fieldDescription, Class<T> type) {
AnnotationDescription.Loadable<Access> access = fieldDescription.getDeclaringType().asErasure().getDeclaredAnnotations().ofType( Access.class );
if ( access != null && access.loadSilent().value() == AccessType.PROPERTY ) {
MethodDescription getter = getterOf( fieldDescription );
if ( getter == null ) {
return fieldDescription.getDeclaredAnnotations().ofType( type );
}
else {
return getter.getDeclaredAnnotations().ofType( type );
}
}
else if ( access != null && access.loadSilent().value() == AccessType.FIELD ) {
return fieldDescription.getDeclaredAnnotations().ofType( type );
}
else {
MethodDescription getter = getterOf( fieldDescription );
if ( getter != null ) {
AnnotationDescription.Loadable<T> annotationDescription = getter.getDeclaredAnnotations().ofType( type );
if ( annotationDescription != null ) {
return annotationDescription;
}
}
return fieldDescription.getDeclaredAnnotations().ofType( type );
}
} }
static MethodDescription getterOf(FieldDescription persistentField) { static MethodDescription getterOf(FieldDescription persistentField) {
MethodList<?> methodList = MethodGraph.Compiler.DEFAULT.compile( persistentField.getDeclaringType().asErasure() ) MethodList<?> methodList = MethodGraph.Compiler.DEFAULT.compile( persistentField.getDeclaringType().asErasure() )
.listNodes() .listNodes()
.asMethodList() .asMethodList()
.filter( isGetter(persistentField.getName() ) ); .filter( isGetter( persistentField.getName() ) );
if ( methodList.size() == 1 ) { if ( methodList.size() == 1 ) {
return methodList.getOnly(); return methodList.getOnly();
} }
@ -469,4 +452,88 @@ public class EnhancerImpl implements Enhancer {
return null; return null;
} }
} }
static class AnnotatedFieldDescription implements UnloadedField {
private final FieldDescription fieldDescription;
private AnnotationList annotations;
AnnotatedFieldDescription(FieldDescription fieldDescription) {
this.fieldDescription = fieldDescription;
}
@Override
public boolean hasAnnotation(Class<? extends Annotation> annotationType) {
return getAnnotations().isAnnotationPresent( annotationType );
}
<T extends Annotation> AnnotationDescription.Loadable<T> getAnnotation(Class<T> annotationType) {
return getAnnotations().ofType( annotationType );
}
String getName() {
return fieldDescription.getName();
}
TypeDefinition getDeclaringType() {
return fieldDescription.getDeclaringType();
}
Generic getType() {
return fieldDescription.getType();
}
InDefinedShape asDefined() {
return fieldDescription.asDefined();
}
String getDescriptor() {
return fieldDescription.getDescriptor();
}
boolean isVisibleTo(TypeDescription typeDescription) {
return fieldDescription.isVisibleTo( typeDescription );
}
FieldDescription getFieldDescription() {
return fieldDescription;
}
private AnnotationList getAnnotations() {
if ( annotations == null ) {
annotations = doGetAnnotations( fieldDescription );
}
return annotations;
}
private static AnnotationList doGetAnnotations(FieldDescription fieldDescription) {
AnnotationDescription.Loadable<Access> access = fieldDescription.getDeclaringType().asErasure()
.getDeclaredAnnotations().ofType( Access.class );
if ( access != null && access.loadSilent().value() == AccessType.PROPERTY ) {
MethodDescription getter = getterOf( fieldDescription );
if ( getter == null ) {
return fieldDescription.getDeclaredAnnotations();
}
else {
return getter.getDeclaredAnnotations();
}
}
else if ( access != null && access.loadSilent().value() == AccessType.FIELD ) {
return fieldDescription.getDeclaredAnnotations();
}
else {
MethodDescription getter = getterOf( fieldDescription );
// Note that the order here is important
List<AnnotationDescription> annotationDescriptions = new ArrayList<>();
if ( getter != null ) {
annotationDescriptions.addAll( getter.getDeclaredAnnotations() );
}
annotationDescriptions.addAll( fieldDescription.getDeclaredAnnotations() );
return fieldDescription.getDeclaredAnnotations();
}
}
}
} }

View File

@ -6,16 +6,18 @@
*/ */
package org.hibernate.bytecode.enhance.internal.bytebuddy; package org.hibernate.bytecode.enhance.internal.bytebuddy;
import static net.bytebuddy.matcher.ElementMatchers.hasDescriptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import javax.persistence.Id; import javax.persistence.Id;
import net.bytebuddy.description.method.MethodList; import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancementException; import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import net.bytebuddy.asm.AsmVisitorWrapper; import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList; import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
@ -25,9 +27,6 @@ import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.jar.asm.Type; import net.bytebuddy.jar.asm.Type;
import net.bytebuddy.pool.TypePool; import net.bytebuddy.pool.TypePool;
import static net.bytebuddy.matcher.ElementMatchers.hasDescriptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
import java.util.Objects; import java.util.Objects;
final class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper { final class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {
@ -63,13 +62,13 @@ final class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.
return; return;
} }
FieldDescription field = findField( owner, name, desc ); AnnotatedFieldDescription field = findField( owner, name, desc );
if ( ( enhancementContext.isEntityClass( field.getDeclaringType().asErasure() ) if ( ( enhancementContext.isEntityClass( field.getDeclaringType().asErasure() )
|| enhancementContext.isCompositeClass( field.getDeclaringType().asErasure() ) ) || enhancementContext.isCompositeClass( field.getDeclaringType().asErasure() ) )
&& !field.getType().asErasure().equals( managedCtClass ) && !field.getType().asErasure().equals( managedCtClass )
&& enhancementContext.isPersistentField( field ) && enhancementContext.isPersistentField( field )
&& !EnhancerImpl.isAnnotationPresent( field, Id.class ) && !field.hasAnnotation( Id.class )
&& !field.getName().equals( "this$0" ) ) { && !field.getName().equals( "this$0" ) ) {
log.debugf( log.debugf(
@ -110,7 +109,7 @@ final class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.
}; };
} }
private FieldDescription findField(String owner, String name, String desc) { private AnnotatedFieldDescription findField(String owner, String name, String desc) {
//Classpool#describe does not accept '/' in the description name as it expects a class name //Classpool#describe does not accept '/' in the description name as it expects a class name
final String cleanedOwner = owner.replace( '/', '.' ); final String cleanedOwner = owner.replace( '/', '.' );
final TypePool.Resolution resolution = classPool.describe( cleanedOwner ); final TypePool.Resolution resolution = classPool.describe( cleanedOwner );
@ -130,7 +129,7 @@ final class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.
); );
throw new EnhancementException( msg ); throw new EnhancementException( msg );
} }
return fields.getOnly(); return new AnnotatedFieldDescription( fields.getOnly() );
} }
@Override @Override

View File

@ -8,6 +8,7 @@ package org.hibernate.bytecode.enhance.internal.bytebuddy;
import java.util.Objects; import java.util.Objects;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
@ -26,17 +27,17 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
protected final TypeDescription managedCtClass; protected final TypeDescription managedCtClass;
protected final FieldDescription persistentField; protected final AnnotatedFieldDescription persistentField;
protected final FieldDescription.InDefinedShape persistentFieldAsDefined; protected final FieldDescription.InDefinedShape persistentFieldAsDefined;
private FieldReaderAppender(TypeDescription managedCtClass, FieldDescription persistentField) { private FieldReaderAppender(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
this.managedCtClass = managedCtClass; this.managedCtClass = managedCtClass;
this.persistentField = persistentField; this.persistentField = persistentField;
this.persistentFieldAsDefined = persistentField.asDefined(); this.persistentFieldAsDefined = persistentField.asDefined();
} }
static ByteCodeAppender of(TypeDescription managedCtClass, FieldDescription persistentField) { static ByteCodeAppender of(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
if ( !persistentField.isVisibleTo( managedCtClass ) ) { if ( !persistentField.isVisibleTo( managedCtClass ) ) {
return new MethodDispatching( managedCtClass, persistentField ); return new MethodDispatching( managedCtClass, persistentField );
} }
@ -119,7 +120,7 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
private static class FieldWriting extends FieldReaderAppender { private static class FieldWriting extends FieldReaderAppender {
private FieldWriting(TypeDescription managedCtClass, FieldDescription persistentField) { private FieldWriting(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
super( managedCtClass, persistentField ); super( managedCtClass, persistentField );
} }
@ -146,7 +147,7 @@ abstract class FieldReaderAppender implements ByteCodeAppender {
private static class MethodDispatching extends FieldReaderAppender { private static class MethodDispatching extends FieldReaderAppender {
private MethodDispatching(TypeDescription managedCtClass, FieldDescription persistentField) { private MethodDispatching(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
super( managedCtClass, persistentField ); super( managedCtClass, persistentField );
} }

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.bytecode.enhance.internal.bytebuddy; package org.hibernate.bytecode.enhance.internal.bytebuddy;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
@ -31,7 +32,7 @@ abstract class FieldWriterAppender implements ByteCodeAppender {
this.persistentFieldAsDefined = persistentFieldAsDefined; this.persistentFieldAsDefined = persistentFieldAsDefined;
} }
static ByteCodeAppender of(TypeDescription managedCtClass, FieldDescription persistentField) { static ByteCodeAppender of(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
if ( !persistentField.isVisibleTo( managedCtClass ) ) { if ( !persistentField.isVisibleTo( managedCtClass ) ) {
return new MethodDispatching( managedCtClass, persistentField.asDefined() ); return new MethodDispatching( managedCtClass, persistentField.asDefined() );
} }

View File

@ -8,10 +8,12 @@ package org.hibernate.bytecode.enhance.internal.bytebuddy;
import java.util.Collection; import java.util.Collection;
import java.util.Objects; import java.util.Objects;
import javax.persistence.Embedded; import javax.persistence.Embedded;
import javax.persistence.EmbeddedId; import javax.persistence.EmbeddedId;
import javax.persistence.Id; import javax.persistence.Id;
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import net.bytebuddy.ClassFileVersion; import net.bytebuddy.ClassFileVersion;
@ -44,25 +46,26 @@ final class InlineDirtyCheckingHandler implements Implementation, ByteCodeAppend
static Implementation wrap( static Implementation wrap(
TypeDescription managedCtClass, TypeDescription managedCtClass,
ByteBuddyEnhancementContext enhancementContext, ByteBuddyEnhancementContext enhancementContext,
FieldDescription persistentField, AnnotatedFieldDescription persistentField,
Implementation implementation) { Implementation implementation) {
if ( enhancementContext.doDirtyCheckingInline( managedCtClass ) ) { if ( enhancementContext.doDirtyCheckingInline( managedCtClass ) ) {
if ( enhancementContext.isCompositeClass( managedCtClass ) ) { if ( enhancementContext.isCompositeClass( managedCtClass ) ) {
implementation = Advice.to( CodeTemplates.CompositeDirtyCheckingHandler.class ).wrap( implementation ); implementation = Advice.to( CodeTemplates.CompositeDirtyCheckingHandler.class ).wrap( implementation );
} }
else if ( !EnhancerImpl.isAnnotationPresent( persistentField, Id.class ) else if ( !persistentField.hasAnnotation( Id.class )
&& !EnhancerImpl.isAnnotationPresent( persistentField, EmbeddedId.class ) && !persistentField.hasAnnotation( EmbeddedId.class )
&& !( persistentField.getType().asErasure().isAssignableTo( Collection.class ) && !( persistentField.getType().asErasure().isAssignableTo( Collection.class )
&& enhancementContext.isMappedCollection( persistentField ) ) ) { && enhancementContext.isMappedCollection( persistentField ) ) ) {
implementation = new InlineDirtyCheckingHandler( implementation, managedCtClass, persistentField.asDefined() ); implementation = new InlineDirtyCheckingHandler( implementation, managedCtClass,
persistentField.asDefined() );
} }
if ( enhancementContext.isCompositeClass( persistentField.getType().asErasure() ) if ( enhancementContext.isCompositeClass( persistentField.getType().asErasure() )
&& EnhancerImpl.isAnnotationPresent( persistentField, Embedded.class ) ) { && persistentField.hasAnnotation( Embedded.class ) ) {
implementation = Advice.withCustomMapping() implementation = Advice.withCustomMapping()
.bind( CodeTemplates.FieldValue.class, persistentField ) .bind( CodeTemplates.FieldValue.class, persistentField.getFieldDescription() )
.bind( CodeTemplates.FieldName.class, persistentField.getName() ) .bind( CodeTemplates.FieldName.class, persistentField.getName() )
.to( CodeTemplates.CompositeFieldDirtyCheckingHandler.class ) .to( CodeTemplates.CompositeFieldDirtyCheckingHandler.class )
.wrap( implementation ); .wrap( implementation );

View File

@ -6,6 +6,9 @@
*/ */
package org.hibernate.bytecode.enhance.internal.bytebuddy; package org.hibernate.bytecode.enhance.internal.bytebuddy;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.not;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -15,14 +18,12 @@ import java.util.Objects;
import javax.persistence.Embedded; import javax.persistence.Embedded;
import net.bytebuddy.description.field.FieldList; import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerImpl.AnnotatedFieldDescription;
import net.bytebuddy.description.method.MethodList;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants; import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.engine.spi.CompositeOwner; import org.hibernate.engine.spi.CompositeOwner;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.AsmVisitorWrapper; import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription; import net.bytebuddy.description.field.FieldDescription;
@ -40,9 +41,6 @@ import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.jar.asm.Type; import net.bytebuddy.jar.asm.Type;
import net.bytebuddy.pool.TypePool; import net.bytebuddy.pool.TypePool;
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
import static net.bytebuddy.matcher.ElementMatchers.not;
final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper { final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {
private static final CoreMessageLogger log = CoreLogging.messageLogger( PersistentAttributeTransformer.class ); private static final CoreMessageLogger log = CoreLogging.messageLogger( PersistentAttributeTransformer.class );
@ -53,13 +51,13 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
private final TypePool classPool; private final TypePool classPool;
private final FieldDescription[] enhancedFields; private final AnnotatedFieldDescription[] enhancedFields;
private PersistentAttributeTransformer( private PersistentAttributeTransformer(
TypeDescription managedCtClass, TypeDescription managedCtClass,
ByteBuddyEnhancementContext enhancementContext, ByteBuddyEnhancementContext enhancementContext,
TypePool classPool, TypePool classPool,
FieldDescription[] enhancedFields) { AnnotatedFieldDescription[] enhancedFields) {
this.managedCtClass = managedCtClass; this.managedCtClass = managedCtClass;
this.enhancementContext = enhancementContext; this.enhancementContext = enhancementContext;
this.classPool = classPool; this.classPool = classPool;
@ -70,14 +68,15 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
TypeDescription managedCtClass, TypeDescription managedCtClass,
ByteBuddyEnhancementContext enhancementContext, ByteBuddyEnhancementContext enhancementContext,
TypePool classPool) { TypePool classPool) {
List<FieldDescription> persistentFieldList = new ArrayList<FieldDescription>(); List<AnnotatedFieldDescription> persistentFieldList = new ArrayList<>();
for ( FieldDescription ctField : managedCtClass.getDeclaredFields() ) { for ( FieldDescription ctField : managedCtClass.getDeclaredFields() ) {
// skip static fields and skip fields added by enhancement and outer reference in inner classes // skip static fields and skip fields added by enhancement and outer reference in inner classes
if ( ctField.getName().startsWith( "$$_hibernate_" ) || "this$0".equals( ctField.getName() ) ) { if ( ctField.getName().startsWith( "$$_hibernate_" ) || "this$0".equals( ctField.getName() ) ) {
continue; continue;
} }
if ( !ctField.isStatic() && enhancementContext.isPersistentField( ctField ) ) { AnnotatedFieldDescription annotatedField = new AnnotatedFieldDescription( ctField );
persistentFieldList.add( ctField ); if ( !ctField.isStatic() && enhancementContext.isPersistentField( annotatedField ) ) {
persistentFieldList.add( annotatedField );
} }
} }
// HHH-10646 Add fields inherited from @MappedSuperclass // HHH-10646 Add fields inherited from @MappedSuperclass
@ -86,12 +85,12 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
persistentFieldList.addAll( collectInheritPersistentFields( managedCtClass, enhancementContext ) ); persistentFieldList.addAll( collectInheritPersistentFields( managedCtClass, enhancementContext ) );
} }
FieldDescription[] orderedFields = enhancementContext.order( persistentFieldList.toArray( new FieldDescription[0] ) ); AnnotatedFieldDescription[] orderedFields = enhancementContext.order( persistentFieldList.toArray( new AnnotatedFieldDescription[0] ) );
log.debugf( "Persistent fields for entity %s: %s", managedCtClass.getName(), Arrays.toString( orderedFields ) ); log.debugf( "Persistent fields for entity %s: %s", managedCtClass.getName(), Arrays.toString( orderedFields ) );
return new PersistentAttributeTransformer( managedCtClass, enhancementContext, classPool, orderedFields ); return new PersistentAttributeTransformer( managedCtClass, enhancementContext, classPool, orderedFields );
} }
private static Collection<FieldDescription> collectInheritPersistentFields( private static Collection<AnnotatedFieldDescription> collectInheritPersistentFields(
TypeDefinition managedCtClass, TypeDefinition managedCtClass,
ByteBuddyEnhancementContext enhancementContext) { ByteBuddyEnhancementContext enhancementContext) {
if ( managedCtClass == null || managedCtClass.represents( Object.class ) ) { if ( managedCtClass == null || managedCtClass.represents( Object.class ) ) {
@ -102,15 +101,18 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
if ( !enhancementContext.isMappedSuperclassClass( managedCtSuperclass.asErasure() ) ) { if ( !enhancementContext.isMappedSuperclassClass( managedCtSuperclass.asErasure() ) ) {
return collectInheritPersistentFields( managedCtSuperclass, enhancementContext ); return collectInheritPersistentFields( managedCtSuperclass, enhancementContext );
} }
log.debugf( "Found @MappedSuperclass %s to collectPersistenceFields", managedCtSuperclass ); log.debugf( "Found @MappedSuperclass %s to collectPersistenceFields", managedCtSuperclass );
List<FieldDescription> persistentFieldList = new ArrayList<FieldDescription>();
List<AnnotatedFieldDescription> persistentFieldList = new ArrayList<>();
for ( FieldDescription ctField : managedCtSuperclass.getDeclaredFields() ) { for ( FieldDescription ctField : managedCtSuperclass.getDeclaredFields() ) {
if ( ctField.getName().startsWith( "$$_hibernate_" ) || "this$0".equals( ctField.getName() ) ) { if ( ctField.getName().startsWith( "$$_hibernate_" ) || "this$0".equals( ctField.getName() ) ) {
continue; continue;
} }
if ( !ctField.isStatic() && enhancementContext.isPersistentField( ctField ) ) { AnnotatedFieldDescription annotatedField = new AnnotatedFieldDescription( ctField );
persistentFieldList.add( ctField ); if ( !ctField.isStatic() && enhancementContext.isPersistentField( annotatedField ) ) {
persistentFieldList.add( annotatedField );
} }
} }
persistentFieldList.addAll( collectInheritPersistentFields( managedCtSuperclass, enhancementContext ) ); persistentFieldList.addAll( collectInheritPersistentFields( managedCtSuperclass, enhancementContext ) );
@ -157,7 +159,7 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
} }
private boolean isEnhanced(String owner, String name, String desc) { private boolean isEnhanced(String owner, String name, String desc) {
for ( FieldDescription enhancedField : enhancedFields ) { for ( AnnotatedFieldDescription enhancedField : enhancedFields ) {
if ( enhancedField.getName().equals( name ) if ( enhancedField.getName().equals( name )
&& enhancedField.getDescriptor().equals( desc ) && enhancedField.getDescriptor().equals( desc )
&& enhancedField.getDeclaringType().asErasure().getInternalName().equals( owner ) ) { && enhancedField.getDeclaringType().asErasure().getInternalName().equals( owner ) ) {
@ -171,7 +173,7 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
boolean compositeOwner = false; boolean compositeOwner = false;
builder = builder.visit( new AsmVisitorWrapper.ForDeclaredMethods().invokable( not( nameStartsWith( "$$_hibernate_" ) ), this ) ); builder = builder.visit( new AsmVisitorWrapper.ForDeclaredMethods().invokable( not( nameStartsWith( "$$_hibernate_" ) ), this ) );
for ( FieldDescription enhancedField : enhancedFields ) { for ( AnnotatedFieldDescription enhancedField : enhancedFields ) {
builder = builder builder = builder
.defineMethod( .defineMethod(
EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + enhancedField.getName(), EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + enhancedField.getName(),
@ -195,7 +197,7 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
if ( !compositeOwner if ( !compositeOwner
&& !accessor && !accessor
&& EnhancerImpl.isAnnotationPresent( enhancedField, Embedded.class ) && enhancedField.hasAnnotation( Embedded.class )
&& enhancementContext.isCompositeClass( enhancedField.getType().asErasure() ) && enhancementContext.isCompositeClass( enhancedField.getType().asErasure() )
&& enhancementContext.doDirtyCheckingInline( managedCtClass ) ) { && enhancementContext.doDirtyCheckingInline( managedCtClass ) ) {
compositeOwner = true; compositeOwner = true;
@ -219,7 +221,7 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
return builder; return builder;
} }
private Implementation fieldReader(FieldDescription enhancedField) { private Implementation fieldReader(AnnotatedFieldDescription enhancedField) {
if ( !enhancementContext.hasLazyLoadableAttributes( managedCtClass ) || !enhancementContext.isLazyLoadable( enhancedField ) ) { if ( !enhancementContext.hasLazyLoadableAttributes( managedCtClass ) || !enhancementContext.isLazyLoadable( enhancedField ) ) {
if ( enhancedField.getDeclaringType().asErasure().equals( managedCtClass ) ) { if ( enhancedField.getDeclaringType().asErasure().equals( managedCtClass ) ) {
return FieldAccessor.ofField( enhancedField.getName() ).in( enhancedField.getDeclaringType().asErasure() ); return FieldAccessor.ofField( enhancedField.getName() ).in( enhancedField.getDeclaringType().asErasure() );
@ -233,7 +235,7 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
} }
} }
private Implementation fieldWriter(FieldDescription enhancedField) { private Implementation fieldWriter(AnnotatedFieldDescription enhancedField) {
Implementation implementation; Implementation implementation;
if ( !enhancementContext.hasLazyLoadableAttributes( managedCtClass ) || !enhancementContext.isLazyLoadable( enhancedField ) ) { if ( !enhancementContext.hasLazyLoadableAttributes( managedCtClass ) || !enhancementContext.isLazyLoadable( enhancedField ) ) {
if ( enhancedField.getDeclaringType().asErasure().equals( managedCtClass ) ) { if ( enhancedField.getDeclaringType().asErasure().equals( managedCtClass ) ) {
@ -259,9 +261,9 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
private final TypeDescription managedCtClass; private final TypeDescription managedCtClass;
private final FieldDescription persistentField; private final AnnotatedFieldDescription persistentField;
private FieldMethodReader(TypeDescription managedCtClass, FieldDescription persistentField) { private FieldMethodReader(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
this.managedCtClass = managedCtClass; this.managedCtClass = managedCtClass;
this.persistentField = persistentField; this.persistentField = persistentField;
} }
@ -289,9 +291,9 @@ final class PersistentAttributeTransformer implements AsmVisitorWrapper.ForDecla
private final TypeDescription managedCtClass; private final TypeDescription managedCtClass;
private final FieldDescription persistentField; private final AnnotatedFieldDescription persistentField;
private FieldMethodWriter(TypeDescription managedCtClass, FieldDescription persistentField) { private FieldMethodWriter(TypeDescription managedCtClass, AnnotatedFieldDescription persistentField) {
this.managedCtClass = managedCtClass; this.managedCtClass = managedCtClass;
this.persistentField = persistentField; this.persistentField = persistentField;
} }

View File

@ -1,27 +0,0 @@
/*
* 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.bytebuddy;
import java.lang.annotation.Annotation;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import net.bytebuddy.description.field.FieldDescription;
class UnloadedFieldDescription implements UnloadedField {
final FieldDescription fieldDescription;
UnloadedFieldDescription(FieldDescription fieldDescription) {
this.fieldDescription = fieldDescription;
}
@Override
public boolean hasAnnotation(Class<? extends Annotation> annotationType) {
return fieldDescription.getDeclaredAnnotations().isAnnotationPresent( annotationType );
}
}

View File

@ -9,7 +9,6 @@ package org.hibernate.bytecode.enhance.internal.bytebuddy;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import org.hibernate.bytecode.enhance.spi.UnloadedClass; import org.hibernate.bytecode.enhance.spi.UnloadedClass;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;