@@ -1553,7 +1553,19 @@ public static class EntityB {
1553
1553
1554
1554
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)
1555
1555
*/
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 ) ) {
1557
1569
final TableGroup tableGroup = determineTableGroupForFetch (
1558
1570
fetchablePath ,
1559
1571
fetchParent ,
@@ -1631,16 +1643,6 @@ else if ( hasNotFoundAction()
1631
1643
1632
1644
*/
1633
1645
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
- }
1644
1646
final DomainResult <?> keyResult ;
1645
1647
if ( side == ForeignKeyDescriptor .Nature .KEY ) {
1646
1648
final TableGroup tableGroup = sideNature == ForeignKeyDescriptor .Nature .KEY
@@ -1692,6 +1694,22 @@ else if ( hasNotFoundAction()
1692
1694
);
1693
1695
}
1694
1696
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
+
1695
1713
private boolean isAffectedByEnabledFilters (DomainResultCreationState creationState ) {
1696
1714
final LoadQueryInfluencers loadQueryInfluencers = creationState .getSqlAstCreationState ()
1697
1715
.getLoadQueryInfluencers ();
0 commit comments