@@ -1553,7 +1553,19 @@ public static class EntityB {
15531553
15541554 having the left join we don't want to add an extra implicit join that will be translated into an SQL inner join (see HHH-15342)
15551555 */
1556- if ( fetchTiming == FetchTiming .IMMEDIATE && selected ) {
1556+
1557+ final ForeignKeyDescriptor .Nature resolvingKeySideOfForeignKey = creationState .getCurrentlyResolvingForeignKeyPart ();
1558+ final ForeignKeyDescriptor .Nature side ;
1559+ if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor .Nature .KEY && this .sideNature == ForeignKeyDescriptor .Nature .TARGET ) {
1560+ // If we are currently resolving the key part of a foreign key we do not want to add joins.
1561+ // So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
1562+ side = ForeignKeyDescriptor .Nature .KEY ;
1563+ }
1564+ else {
1565+ side = this .sideNature ;
1566+ }
1567+
1568+ if ( ( fetchTiming == FetchTiming .IMMEDIATE && selected ) || needsJoinFetch ( side ) ) {
15571569 final TableGroup tableGroup = determineTableGroupForFetch (
15581570 fetchablePath ,
15591571 fetchParent ,
@@ -1631,16 +1643,6 @@ else if ( hasNotFoundAction()
16311643
16321644 */
16331645
1634- final ForeignKeyDescriptor .Nature resolvingKeySideOfForeignKey = creationState .getCurrentlyResolvingForeignKeyPart ();
1635- final ForeignKeyDescriptor .Nature side ;
1636- if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor .Nature .KEY && this .sideNature == ForeignKeyDescriptor .Nature .TARGET ) {
1637- // If we are currently resolving the key part of a foreign key we do not want to add joins.
1638- // So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
1639- side = ForeignKeyDescriptor .Nature .KEY ;
1640- }
1641- else {
1642- side = this .sideNature ;
1643- }
16441646 final DomainResult <?> keyResult ;
16451647 if ( side == ForeignKeyDescriptor .Nature .KEY ) {
16461648 final TableGroup tableGroup = sideNature == ForeignKeyDescriptor .Nature .KEY
@@ -1692,6 +1694,22 @@ else if ( hasNotFoundAction()
16921694 );
16931695 }
16941696
1697+ private boolean needsJoinFetch (ForeignKeyDescriptor .Nature side ) {
1698+ if ( side == ForeignKeyDescriptor .Nature .TARGET ) {
1699+ // The target model part doesn't correspond to the identifier of the target entity mapping
1700+ // so we must eagerly fetch with a join (subselect would still cause problems).
1701+ final EntityIdentifierMapping identifier = entityMappingType .getIdentifierMapping ();
1702+ final ValuedModelPart targetPart = foreignKeyDescriptor .getTargetPart ();
1703+ if ( identifier != targetPart ) {
1704+ // If the identifier and the target part of the same class, we can preserve laziness as deferred loading will still work
1705+ return identifier .getExpressibleJavaType ().getJavaTypeClass () != targetPart .getExpressibleJavaType ()
1706+ .getJavaTypeClass ();
1707+ }
1708+ }
1709+
1710+ return false ;
1711+ }
1712+
16951713 private boolean isAffectedByEnabledFilters (DomainResultCreationState creationState ) {
16961714 final LoadQueryInfluencers loadQueryInfluencers = creationState .getSqlAstCreationState ()
16971715 .getLoadQueryInfluencers ();
0 commit comments