@@ -630,6 +630,11 @@ private static PropertyData getUniqueIdPropertyFromBaseClass(
630
630
return baseClassElements .get ( 0 );
631
631
}
632
632
633
+ /**
634
+ * Given the id class of the current entity, as specified by an
635
+ * {@link IdClass} annotation, determine if it's actually the
636
+ * identifier type or {@link IdClass} of some associated entity.
637
+ */
633
638
private boolean isIdClassPrimaryKeyOfAssociatedEntity (
634
639
ElementsToProcess elementsToProcess ,
635
640
ClassDetails compositeClass ,
@@ -639,26 +644,39 @@ private boolean isIdClassPrimaryKeyOfAssociatedEntity(
639
644
Map <ClassDetails , InheritanceState > inheritanceStates ,
640
645
MetadataBuildingContext context ) {
641
646
if ( elementsToProcess .getIdPropertyCount () == 1 ) {
647
+ // There's only one @Id field, so it might be the @EmbeddedId of an associated
648
+ // entity referenced via a @ManyToOne or @OneToOne association
642
649
final PropertyData idPropertyOnBaseClass =
643
650
getUniqueIdPropertyFromBaseClass ( inferredData , baseInferredData , propertyAccessor , context );
644
651
final InheritanceState state =
645
652
inheritanceStates .get ( idPropertyOnBaseClass .getClassOrElementType ().determineRawClass () );
646
653
if ( state == null ) {
647
- return false ; //while it is likely a user error, let's consider it is something that might happen
648
- }
649
- final ClassDetails associatedClassWithIdClass = state .getClassWithIdClass ( true );
650
- if ( associatedClassWithIdClass == null ) {
651
- //we cannot know for sure here unless we try and find the @EmbeddedId
652
- //Let's not do this thorough checking but do some extra validation
653
- return hasToOneAnnotation ( idPropertyOnBaseClass .getAttributeMember () );
654
-
654
+ // Likely a user error, but treat it as something that might happen
655
+ return false ;
655
656
}
656
657
else {
657
- final IdClass idClass = associatedClassWithIdClass .getAnnotationUsage ( IdClass .class , modelsContext () );
658
- return compositeClass .getName ().equals ( idClass .value ().getName () );
658
+ final ClassDetails associatedClassWithIdClass = state .getClassWithIdClass ( true );
659
+ if ( associatedClassWithIdClass == null ) {
660
+ // We cannot know for sure here without looking at the identifier
661
+ // type of the associated entity. Instead of doing that, we look to
662
+ // see if our @Id field has a @ManyToOne or @OneToOne annotation,
663
+ // making the possibly wrong assumption that an @Id @ManyToOne or
664
+ // @Id @OneToOne always has the type of the associated entity, and
665
+ // is never a different @IdClass with a single field just holding
666
+ // the PK of the associated entity.
667
+ return hasToOneAnnotation ( idPropertyOnBaseClass .getAttributeMember () );
668
+ }
669
+ else {
670
+ // The associated entity has an @IdClass, so check if it's the same
671
+ final IdClass idClass =
672
+ associatedClassWithIdClass .getAnnotationUsage ( IdClass .class , modelsContext () );
673
+ return compositeClass .getName ().equals ( idClass .value ().getName () );
674
+ }
659
675
}
660
676
}
661
677
else {
678
+ // There are multiple @Id fields, so we know for sure that the id class of
679
+ // this entity can't be the identifier type of the associated entity
662
680
return false ;
663
681
}
664
682
}
0 commit comments