Skip to content

Commit b474cba

Browse files
dreab8beikov
authored andcommitted
HHH-17838 @OnetoOne relationship + @embeddable keys + FetchType.LAZY fail
1 parent dfee51c commit b474cba

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,19 @@ public static class EntityB {
15571557
15581558
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)
15591559
*/
1560-
if ( fetchTiming == FetchTiming.IMMEDIATE && selected ) {
1560+
1561+
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
1562+
final ForeignKeyDescriptor.Nature side;
1563+
if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
1564+
// If we are currently resolving the key part of a foreign key we do not want to add joins.
1565+
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
1566+
side = ForeignKeyDescriptor.Nature.KEY;
1567+
}
1568+
else {
1569+
side = this.sideNature;
1570+
}
1571+
1572+
if ( ( fetchTiming == FetchTiming.IMMEDIATE && selected ) || needsJoinFetch( side ) ) {
15611573
final TableGroup tableGroup = determineTableGroupForFetch(
15621574
fetchablePath,
15631575
fetchParent,
@@ -1635,16 +1647,6 @@ else if ( hasNotFoundAction()
16351647
16361648
*/
16371649

1638-
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
1639-
final ForeignKeyDescriptor.Nature side;
1640-
if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
1641-
// If we are currently resolving the key part of a foreign key we do not want to add joins.
1642-
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
1643-
side = ForeignKeyDescriptor.Nature.KEY;
1644-
}
1645-
else {
1646-
side = this.sideNature;
1647-
}
16481650
final DomainResult<?> keyResult;
16491651
if ( side == ForeignKeyDescriptor.Nature.KEY ) {
16501652
final TableGroup tableGroup = sideNature == ForeignKeyDescriptor.Nature.KEY
@@ -1696,6 +1698,22 @@ else if ( hasNotFoundAction()
16961698
);
16971699
}
16981700

1701+
private boolean needsJoinFetch(ForeignKeyDescriptor.Nature side) {
1702+
if ( side == ForeignKeyDescriptor.Nature.TARGET ) {
1703+
// The target model part doesn't correspond to the identifier of the target entity mapping
1704+
// so we must eagerly fetch with a join (subselect would still cause problems).
1705+
final EntityIdentifierMapping identifier = entityMappingType.getIdentifierMapping();
1706+
final ValuedModelPart targetPart = foreignKeyDescriptor.getTargetPart();
1707+
if ( identifier != targetPart ) {
1708+
// If the identifier and the target part of the same class, we can preserve laziness as deferred loading will still work
1709+
return identifier.getExpressibleJavaType().getJavaTypeClass() != targetPart.getExpressibleJavaType()
1710+
.getJavaTypeClass();
1711+
}
1712+
}
1713+
1714+
return false;
1715+
}
1716+
16991717
private boolean isAffectedByEnabledFilters(DomainResultCreationState creationState) {
17001718
final LoadQueryInfluencers loadQueryInfluencers = creationState.getSqlAstCreationState()
17011719
.getLoadQueryInfluencers();

0 commit comments

Comments
 (0)