@@ -630,6 +630,11 @@ private static PropertyData getUniqueIdPropertyFromBaseClass(
630630 return baseClassElements .get ( 0 );
631631 }
632632
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+ */
633638 private boolean isIdClassPrimaryKeyOfAssociatedEntity (
634639 ElementsToProcess elementsToProcess ,
635640 ClassDetails compositeClass ,
@@ -639,26 +644,39 @@ private boolean isIdClassPrimaryKeyOfAssociatedEntity(
639644 Map <ClassDetails , InheritanceState > inheritanceStates ,
640645 MetadataBuildingContext context ) {
641646 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
642649 final PropertyData idPropertyOnBaseClass =
643650 getUniqueIdPropertyFromBaseClass ( inferredData , baseInferredData , propertyAccessor , context );
644651 final InheritanceState state =
645652 inheritanceStates .get ( idPropertyOnBaseClass .getClassOrElementType ().determineRawClass () );
646653 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 ;
655656 }
656657 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+ }
659675 }
660676 }
661677 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
662680 return false ;
663681 }
664682 }
0 commit comments