HHH-16313 HHH-16313 Check mappedBy type when binding entity associations
This commit is contained in:
parent
d0aff04fc6
commit
7f2a3917f4
|
@ -1071,4 +1071,34 @@ public class BinderHelper {
|
|||
public static boolean isDefault(XClass clazz, MetadataBuildingContext context) {
|
||||
return context.getBootstrapContext().getReflectionManager().equals( clazz, void.class );
|
||||
}
|
||||
|
||||
public static void checkMappedByType(
|
||||
String mappedBy,
|
||||
Value targetValue,
|
||||
String propertyName,
|
||||
PropertyHolder propertyHolder) {
|
||||
final ToOne toOne;
|
||||
if ( targetValue instanceof Collection ) {
|
||||
toOne = (ToOne) ( (Collection) targetValue ).getElement();
|
||||
}
|
||||
else {
|
||||
toOne = (ToOne) targetValue;
|
||||
}
|
||||
final String referencedEntityName = toOne.getReferencedEntityName();
|
||||
PersistentClass referencedClass = propertyHolder.getPersistentClass();
|
||||
while ( referencedClass != null ) {
|
||||
if ( referencedClass.getEntityName().equals( referencedEntityName ) ) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
referencedClass = referencedClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
throw new AnnotationException(
|
||||
"Association '" + qualify( propertyHolder.getPath(), propertyName )
|
||||
+ "' is 'mappedBy' a property named '" + mappedBy
|
||||
+ "' which references the wrong entity type '" + referencedEntityName
|
||||
+ "', expected '" + propertyHolder.getEntityName() + "'"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,6 +153,7 @@ import static org.hibernate.boot.model.internal.AnnotatedColumn.buildFormulaFrom
|
|||
import static org.hibernate.boot.model.internal.AnnotatedJoinColumns.buildJoinColumnsWithDefaultColumnSuffix;
|
||||
import static org.hibernate.boot.model.internal.AnnotatedJoinColumns.buildJoinTableJoinColumns;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.buildAnyValue;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.checkMappedByType;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.createSyntheticPropertyReference;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode;
|
||||
|
@ -171,7 +172,6 @@ import static org.hibernate.internal.util.StringHelper.isEmpty;
|
|||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
|
||||
import static org.hibernate.internal.util.StringHelper.qualify;
|
||||
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
|
||||
|
||||
/**
|
||||
* Base class for stateful binders responsible for producing mapping model objects of type {@link Collection}.
|
||||
|
@ -1555,14 +1555,19 @@ public abstract class CollectionBinder {
|
|||
|
||||
private boolean isReversePropertyInJoin(XClass elementType, PersistentClass persistentClass) {
|
||||
if ( persistentClass != null && isUnownedCollection() ) {
|
||||
final Property mappedByProperty;
|
||||
try {
|
||||
return persistentClass.getJoinNumber( persistentClass.getRecursiveProperty( mappedBy ) ) != 0;
|
||||
mappedByProperty = persistentClass.getRecursiveProperty( mappedBy );
|
||||
}
|
||||
catch (MappingException e) {
|
||||
throw new AnnotationException( "Collection '" + safeCollectionRole()
|
||||
throw new AnnotationException(
|
||||
"Collection '" + safeCollectionRole()
|
||||
+ "' is 'mappedBy' a property named '" + mappedBy
|
||||
+ "' which does not exist in the target entity '" + elementType.getName() + "'" );
|
||||
+ "' which does not exist in the target entity '" + elementType.getName() + "'"
|
||||
);
|
||||
}
|
||||
checkMappedByType( mappedBy, mappedByProperty.getValue(), propertyName, propertyHolder );
|
||||
return persistentClass.getJoinNumber( mappedByProperty ) != 0;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.type.ForeignKeyDirection;
|
|||
|
||||
import jakarta.persistence.ForeignKey;
|
||||
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.checkMappedByType;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.findPropertyByName;
|
||||
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
|
||||
import static org.hibernate.boot.model.internal.ToOneBinder.bindForeignKeyNameAndDefinition;
|
||||
|
@ -152,6 +153,7 @@ public class OneToOneSecondPass implements SecondPass {
|
|||
+ "' of the target entity type '" + oneToOne.getReferencedEntityName()
|
||||
+ "' which is not a '@OneToOne' or '@ManyToOne' association" );
|
||||
}
|
||||
checkMappedByType( mappedBy, targetProperty.getValue(), oneToOne.getPropertyName(), propertyHolder );
|
||||
}
|
||||
|
||||
private void bindTargetManyToOne(
|
||||
|
|
|
@ -152,7 +152,7 @@ public class PolymorphicAssociationTest2 {
|
|||
private String name;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY)
|
||||
private DerivedLevel2 level2Parent;
|
||||
private Level2 level2Parent;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
|
@ -170,11 +170,11 @@ public class PolymorphicAssociationTest2 {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public DerivedLevel2 getLevel2Parent() {
|
||||
public Level2 getLevel2Parent() {
|
||||
return level2Parent;
|
||||
}
|
||||
|
||||
public void setLevel2Parent(DerivedLevel2 level2Parent) {
|
||||
public void setLevel2Parent(Level2 level2Parent) {
|
||||
this.level2Parent = level2Parent;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue