HHH-16908 Mapping error when using unowned associations as identifiers

This commit is contained in:
Marco Belladelli 2023-07-19 14:52:16 +02:00
parent 93b1b6a48c
commit 28d9c65293
2 changed files with 24 additions and 3 deletions

View File

@ -208,7 +208,7 @@ public class OneToOneSecondPass implements SecondPass {
final KeyValue targetEntityIdentifier = targetEntity.getIdentifier(); final KeyValue targetEntityIdentifier = targetEntity.getIdentifier();
boolean referenceToPrimaryKey = mappedBy == null boolean referenceToPrimaryKey = mappedBy == null
|| targetEntityIdentifier instanceof Component || targetEntityIdentifier instanceof Component
&& !( (Component) targetEntityIdentifier ).hasProperty( mappedBy ); && ( (Component) targetEntityIdentifier ).hasProperty( mappedBy );
oneToOne.setReferenceToPrimaryKey( referenceToPrimaryKey ); oneToOne.setReferenceToPrimaryKey( referenceToPrimaryKey );
final String propertyRef = oneToOne.getReferencedPropertyName(); final String propertyRef = oneToOne.getReferencedPropertyName();

View File

@ -90,11 +90,18 @@ public class ToOneBinder {
if ( property.isAnnotationPresent( Column.class ) if ( property.isAnnotationPresent( Column.class )
|| property.isAnnotationPresent( Columns.class ) ) { || property.isAnnotationPresent( Columns.class ) ) {
throw new AnnotationException( throw new AnnotationException(
"Property '"+ getPath( propertyHolder, inferredData ) "Property '" + getPath( propertyHolder, inferredData )
+ "' is a '@ManyToOne' association and may not use '@Column' to specify column mappings (use '@JoinColumn' instead)" + "' is a '@ManyToOne' association and may not use '@Column' to specify column mappings (use '@JoinColumn' instead)"
); );
} }
if ( joinColumns.hasMappedBy() && isIdentifier( propertyHolder, propertyBinder, isIdentifierMapper ) ) {
throw new AnnotationException(
"Property '" + getPath( propertyHolder, inferredData )
+ "' is the inverse side of a '@ManyToOne' association and cannot be used as identifier"
);
}
final Cascade hibernateCascade = property.getAnnotation( Cascade.class ); final Cascade hibernateCascade = property.getAnnotation( Cascade.class );
final NotFound notFound = property.getAnnotation( NotFound.class ); final NotFound notFound = property.getAnnotation( NotFound.class );
final NotFoundAction notFoundAction = notFound == null ? null : notFound.action(); final NotFoundAction notFoundAction = notFound == null ? null : notFound.action();
@ -124,6 +131,13 @@ public class ToOneBinder {
); );
} }
private static boolean isIdentifier(
PropertyHolder propertyHolder,
PropertyBinder propertyBinder,
boolean isIdentifierMapper) {
return propertyBinder.isId() || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass() || isIdentifierMapper;
}
private static boolean isMandatory(boolean optional, XProperty property, NotFoundAction notFoundAction) { private static boolean isMandatory(boolean optional, XProperty property, NotFoundAction notFoundAction) {
// @MapsId means the columns belong to the pk; // @MapsId means the columns belong to the pk;
// A @MapsId association (obviously) must be non-null when the entity is first persisted. // A @MapsId association (obviously) must be non-null when the entity is first persisted.
@ -421,12 +435,19 @@ public class ToOneBinder {
if ( property.isAnnotationPresent( Column.class ) if ( property.isAnnotationPresent( Column.class )
|| property.isAnnotationPresent( Columns.class ) ) { || property.isAnnotationPresent( Columns.class ) ) {
throw new AnnotationException( throw new AnnotationException(
"Property '"+ getPath( propertyHolder, inferredData ) "Property '" + getPath( propertyHolder, inferredData )
+ "' is a '@OneToOne' association and may not use '@Column' to specify column mappings" + "' is a '@OneToOne' association and may not use '@Column' to specify column mappings"
+ " (use '@PrimaryKeyJoinColumn' instead)" + " (use '@PrimaryKeyJoinColumn' instead)"
); );
} }
if ( joinColumns.hasMappedBy() && isIdentifier( propertyHolder, propertyBinder, isIdentifierMapper ) ) {
throw new AnnotationException(
"Property '" + getPath( propertyHolder, inferredData )
+ "' is the inverse side of a '@OneToOne' association and cannot be used as identifier"
);
}
//FIXME support a proper PKJCs //FIXME support a proper PKJCs
final boolean trueOneToOne = property.isAnnotationPresent( PrimaryKeyJoinColumn.class ) final boolean trueOneToOne = property.isAnnotationPresent( PrimaryKeyJoinColumn.class )
|| property.isAnnotationPresent( PrimaryKeyJoinColumns.class ); || property.isAnnotationPresent( PrimaryKeyJoinColumns.class );