HHH-13446 - Validate mapped-by values got from annotations in bytecode enhancers
This commit is contained in:
parent
b4a8052a15
commit
1dd787eaa1
|
@ -58,9 +58,10 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
|||
String mappedBy = getMappedBy( persistentField, targetEntity, enhancementContext );
|
||||
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
||||
log.infof(
|
||||
"Could not find bi-directional association for field [%s#%s]",
|
||||
"Bi-directional association not managed for field [%s#%s]: Could not find target field in [%s]",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
persistentField.getName(),
|
||||
targetEntity.getCanonicalName()
|
||||
);
|
||||
return implementation;
|
||||
}
|
||||
|
@ -101,7 +102,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
|||
|
||||
if ( persistentField.getType().asErasure().isAssignableTo( Map.class ) || targetType.isAssignableTo( Map.class ) ) {
|
||||
log.infof(
|
||||
"Bi-directional association for field [%s#%s] not managed: @ManyToMany in java.util.Map attribute not supported ",
|
||||
"Bi-directional association not managed for field [%s#%s]: @ManyToMany in java.util.Map attribute not supported ",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
);
|
||||
|
@ -145,7 +146,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
|||
|
||||
if ( targetClass == null ) {
|
||||
log.infof(
|
||||
"Could not find type of bi-directional association for field [%s#%s]",
|
||||
"Bi-directional association not managed for field [%s#%s]: Could not find target type",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
);
|
||||
|
@ -183,7 +184,20 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
|||
return getMappedByManyToMany( target, targetEntity, context );
|
||||
}
|
||||
else {
|
||||
return mappedBy;
|
||||
// HHH-13446 - mappedBy from annotation may not be a valid bi-directional association, verify by calling isValidMappedBy()
|
||||
return isValidMappedBy( target, targetEntity, mappedBy, context ) ? mappedBy : "";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidMappedBy(AnnotatedFieldDescription persistentField, TypeDescription targetEntity, String mappedBy, ByteBuddyEnhancementContext context) {
|
||||
try {
|
||||
FieldDescription f = FieldLocator.ForClassHierarchy.Factory.INSTANCE.make( targetEntity ).locate( mappedBy ).getField();
|
||||
AnnotatedFieldDescription annotatedF = new AnnotatedFieldDescription( context, f );
|
||||
|
||||
return context.isPersistentField( annotatedF ) && persistentField.getDeclaringType().asErasure().isAssignableTo( entityType( f.getType() ) );
|
||||
}
|
||||
catch ( IllegalStateException e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ public class PersistentAttributesEnhancer extends EnhancerImpl {
|
|||
final CtClass targetEntity = PersistentAttributesHelper.getTargetEntityClass( managedCtClass, persistentField );
|
||||
if ( targetEntity == null ) {
|
||||
log.infof(
|
||||
"Could not find type of bi-directional association for field [%s#%s]",
|
||||
"Bi-directional association not managed for field [%s#%s]: Could not find target type",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
);
|
||||
|
@ -334,9 +334,10 @@ public class PersistentAttributesEnhancer extends EnhancerImpl {
|
|||
final String mappedBy = PersistentAttributesHelper.getMappedBy( persistentField, targetEntity, enhancementContext );
|
||||
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
||||
log.infof(
|
||||
"Could not find bi-directional association for field [%s#%s]",
|
||||
"Bi-directional association not managed for field [%s#%s]: Could not find target field in [%s]",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
persistentField.getName(),
|
||||
targetEntity.getName()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -459,7 +460,7 @@ public class PersistentAttributesEnhancer extends EnhancerImpl {
|
|||
if ( PersistentAttributesHelper.isAssignable( persistentField.getType(), Map.class.getName() ) ||
|
||||
PersistentAttributesHelper.isAssignable( targetEntity.getField( mappedBy ).getType(), Map.class.getName() ) ) {
|
||||
log.infof(
|
||||
"Bi-directional association for field [%s#%s] not managed: @ManyToMany in java.util.Map attribute not supported ",
|
||||
"Bi-directional association not managed for field [%s#%s]: @ManyToMany in java.util.Map attribute not supported ",
|
||||
managedCtClass.getName(),
|
||||
persistentField.getName()
|
||||
);
|
||||
|
|
|
@ -209,7 +209,23 @@ public class PersistentAttributesHelper {
|
|||
|
||||
public static String getMappedBy(CtField persistentField, CtClass targetEntity, JavassistEnhancementContext context) throws NotFoundException {
|
||||
final String local = getMappedByFromAnnotation( persistentField );
|
||||
return local.isEmpty() ? getMappedByFromTargetEntity( persistentField, targetEntity, context ) : local;
|
||||
if ( local == null || local.isEmpty() ) {
|
||||
return getMappedByFromTargetEntity( persistentField, targetEntity, context );
|
||||
}
|
||||
else {
|
||||
// HHH-13446 - mappedBy from annotation may not be a valid bi-directional association, verify by calling isValidMappedBy()
|
||||
return isValidMappedBy( persistentField, targetEntity, local, context ) ? local : "";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidMappedBy(CtField persistentField, CtClass targetEntity, String mappedBy, JavassistEnhancementContext context) {
|
||||
try {
|
||||
CtField f = targetEntity.getField( mappedBy );
|
||||
return context.isPersistentField( f ) && isAssignable( persistentField.getDeclaringClass(), inferFieldTypeName( f ) );
|
||||
}
|
||||
catch ( NotFoundException e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMappedByFromAnnotation(CtField persistentField) {
|
||||
|
|
|
@ -73,6 +73,10 @@ public class OneToManyAssociationTest {
|
|||
|
||||
String name;
|
||||
|
||||
// HHH-13446 - Type not validated in bi-directional association mapping
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "custId", fetch = FetchType.EAGER)
|
||||
List<CustomerInventory> inventoryIdList = new ArrayList<>();
|
||||
|
||||
@OneToMany( mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER )
|
||||
List<CustomerInventory> customerInventories = new ArrayList<>();
|
||||
|
||||
|
|
Loading…
Reference in New Issue