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 );
|
String mappedBy = getMappedBy( persistentField, targetEntity, enhancementContext );
|
||||||
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
||||||
log.infof(
|
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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName(),
|
||||||
|
targetEntity.getCanonicalName()
|
||||||
);
|
);
|
||||||
return implementation;
|
return implementation;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
||||||
|
|
||||||
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(
|
||||||
"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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName()
|
||||||
);
|
);
|
||||||
|
@ -145,7 +146,7 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
||||||
|
|
||||||
if ( targetClass == null ) {
|
if ( targetClass == null ) {
|
||||||
log.infof(
|
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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName()
|
||||||
);
|
);
|
||||||
|
@ -183,7 +184,20 @@ final class BiDirectionalAssociationHandler implements Implementation {
|
||||||
return getMappedByManyToMany( target, targetEntity, context );
|
return getMappedByManyToMany( target, targetEntity, context );
|
||||||
}
|
}
|
||||||
else {
|
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 );
|
final CtClass targetEntity = PersistentAttributesHelper.getTargetEntityClass( managedCtClass, persistentField );
|
||||||
if ( targetEntity == null ) {
|
if ( targetEntity == null ) {
|
||||||
log.infof(
|
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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName()
|
||||||
);
|
);
|
||||||
|
@ -334,9 +334,10 @@ public class PersistentAttributesEnhancer extends EnhancerImpl {
|
||||||
final String mappedBy = PersistentAttributesHelper.getMappedBy( persistentField, targetEntity, enhancementContext );
|
final String mappedBy = PersistentAttributesHelper.getMappedBy( persistentField, targetEntity, enhancementContext );
|
||||||
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
if ( mappedBy == null || mappedBy.isEmpty() ) {
|
||||||
log.infof(
|
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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName(),
|
||||||
|
targetEntity.getName()
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -459,7 +460,7 @@ public class PersistentAttributesEnhancer extends EnhancerImpl {
|
||||||
if ( PersistentAttributesHelper.isAssignable( persistentField.getType(), Map.class.getName() ) ||
|
if ( PersistentAttributesHelper.isAssignable( persistentField.getType(), Map.class.getName() ) ||
|
||||||
PersistentAttributesHelper.isAssignable( targetEntity.getField( mappedBy ).getType(), Map.class.getName() ) ) {
|
PersistentAttributesHelper.isAssignable( targetEntity.getField( mappedBy ).getType(), Map.class.getName() ) ) {
|
||||||
log.infof(
|
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(),
|
managedCtClass.getName(),
|
||||||
persistentField.getName()
|
persistentField.getName()
|
||||||
);
|
);
|
||||||
|
|
|
@ -209,7 +209,23 @@ public class PersistentAttributesHelper {
|
||||||
|
|
||||||
public static String getMappedBy(CtField persistentField, CtClass targetEntity, JavassistEnhancementContext context) throws NotFoundException {
|
public static String getMappedBy(CtField persistentField, CtClass targetEntity, JavassistEnhancementContext context) throws NotFoundException {
|
||||||
final String local = getMappedByFromAnnotation( persistentField );
|
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) {
|
private static String getMappedByFromAnnotation(CtField persistentField) {
|
||||||
|
|
|
@ -73,6 +73,10 @@ public class OneToManyAssociationTest {
|
||||||
|
|
||||||
String name;
|
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 )
|
@OneToMany( mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER )
|
||||||
List<CustomerInventory> customerInventories = new ArrayList<>();
|
List<CustomerInventory> customerInventories = new ArrayList<>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue