Skip to content

Commit 2a70f06

Browse files
dreab8sebersole
authored andcommitted
HHH-17838 @OnetoOne relationship + @embeddable keys + FetchType.LAZY fail
1 parent 406ab5b commit 2a70f06

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
@@ -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

Comments
 (0)