mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-25 21:04:51 +00:00
HHH-16313 HHH-16313 Check mappedBy type when binding entity associations
This commit is contained in:
parent
d0aff04fc6
commit
7f2a3917f4
@ -1071,4 +1071,34 @@ static boolean isCompositeId(XClass entityClass, XProperty idProperty) {
|
|||||||
public static boolean isDefault(XClass clazz, MetadataBuildingContext context) {
|
public static boolean isDefault(XClass clazz, MetadataBuildingContext context) {
|
||||||
return context.getBootstrapContext().getReflectionManager().equals( clazz, void.class );
|
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.AnnotatedJoinColumns.buildJoinColumnsWithDefaultColumnSuffix;
|
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.AnnotatedJoinColumns.buildJoinTableJoinColumns;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.buildAnyValue;
|
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.createSyntheticPropertyReference;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
|
import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode;
|
import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode;
|
||||||
@ -171,7 +172,6 @@
|
|||||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||||
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
|
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
|
||||||
import static org.hibernate.internal.util.StringHelper.qualify;
|
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}.
|
* Base class for stateful binders responsible for producing mapping model objects of type {@link Collection}.
|
||||||
@ -1555,14 +1555,19 @@ protected boolean bindStarToManySecondPass(Map<String, PersistentClass> persiste
|
|||||||
|
|
||||||
private boolean isReversePropertyInJoin(XClass elementType, PersistentClass persistentClass) {
|
private boolean isReversePropertyInJoin(XClass elementType, PersistentClass persistentClass) {
|
||||||
if ( persistentClass != null && isUnownedCollection() ) {
|
if ( persistentClass != null && isUnownedCollection() ) {
|
||||||
|
final Property mappedByProperty;
|
||||||
try {
|
try {
|
||||||
return persistentClass.getJoinNumber( persistentClass.getRecursiveProperty( mappedBy ) ) != 0;
|
mappedByProperty = persistentClass.getRecursiveProperty( mappedBy );
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch (MappingException e) {
|
||||||
throw new AnnotationException( "Collection '" + safeCollectionRole()
|
throw new AnnotationException(
|
||||||
|
"Collection '" + safeCollectionRole()
|
||||||
+ "' is 'mappedBy' a property named '" + mappedBy
|
+ "' 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 {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
import jakarta.persistence.ForeignKey;
|
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.findPropertyByName;
|
||||||
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
|
import static org.hibernate.boot.model.internal.BinderHelper.getPath;
|
||||||
import static org.hibernate.boot.model.internal.ToOneBinder.bindForeignKeyNameAndDefinition;
|
import static org.hibernate.boot.model.internal.ToOneBinder.bindForeignKeyNameAndDefinition;
|
||||||
@ -152,6 +153,7 @@ else if ( targetProperty.getValue() instanceof ManyToOne ) {
|
|||||||
+ "' of the target entity type '" + oneToOne.getReferencedEntityName()
|
+ "' of the target entity type '" + oneToOne.getReferencedEntityName()
|
||||||
+ "' which is not a '@OneToOne' or '@ManyToOne' association" );
|
+ "' which is not a '@OneToOne' or '@ManyToOne' association" );
|
||||||
}
|
}
|
||||||
|
checkMappedByType( mappedBy, targetProperty.getValue(), oneToOne.getPropertyName(), propertyHolder );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindTargetManyToOne(
|
private void bindTargetManyToOne(
|
||||||
|
@ -152,7 +152,7 @@ static class Level3 {
|
|||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@OneToOne(fetch = FetchType.LAZY)
|
@OneToOne(fetch = FetchType.LAZY)
|
||||||
private DerivedLevel2 level2Parent;
|
private Level2 level2Parent;
|
||||||
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
@ -170,11 +170,11 @@ public void setName(String name) {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DerivedLevel2 getLevel2Parent() {
|
public Level2 getLevel2Parent() {
|
||||||
return level2Parent;
|
return level2Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLevel2Parent(DerivedLevel2 level2Parent) {
|
public void setLevel2Parent(Level2 level2Parent) {
|
||||||
this.level2Parent = level2Parent;
|
this.level2Parent = level2Parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user