Skip to content

Commit dc75f19

Browse files
committed
HHH-18330 Check model part when reusing table group for to-one fetch
1 parent 49261f6 commit dc75f19

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

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

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,52 +1686,59 @@ private TableGroup determineTableGroupForFetch(
16861686
else {
16871687
joinType = null;
16881688
}
1689-
return fromClauseAccess.resolveTableGroup(
1690-
fetchablePath,
1691-
np -> {
1692-
// Try to reuse an existing join if possible,
1693-
// and note that we prefer reusing an inner over a left join,
1694-
// because a left join might stay uninitialized if unused
1695-
TableGroup leftJoined = null;
1696-
for ( TableGroupJoin tableGroupJoin : parentTableGroup.getTableGroupJoins() ) {
1697-
switch ( tableGroupJoin.getJoinType() ) {
1698-
case INNER:
1699-
// If this is an inner joins, it's fine if the paths match
1700-
// Since this inner join would filter the parent row anyway,
1701-
// it makes no sense to add another left join for this association
1702-
if ( tableGroupJoin.getNavigablePath().pathsMatch( np ) ) {
1703-
return tableGroupJoin.getJoinedGroup();
1704-
}
1705-
break;
1706-
case LEFT:
1707-
// For an existing left join on the other hand which is row preserving,
1708-
// it is important to check if the predicate has user defined bits in it
1709-
// and only if it doesn't, we can reuse the join
1710-
if ( tableGroupJoin.getNavigablePath().pathsMatch( np )
1711-
&& isSimpleJoinPredicate( tableGroupJoin.getPredicate() ) ) {
1712-
leftJoined = tableGroupJoin.getJoinedGroup();
1713-
}
1714-
}
1689+
final TableGroup existingTableGroup = fromClauseAccess.findTableGroupForGetOrCreate(
1690+
fetchablePath
1691+
);
1692+
if ( existingTableGroup != null && existingTableGroup.getModelPart() == this ) {
1693+
return existingTableGroup;
1694+
}
1695+
else {
1696+
// Try to reuse an existing join if possible,
1697+
// and note that we prefer reusing an inner over a left join,
1698+
// because a left join might stay uninitialized if unused
1699+
TableGroup leftJoined = null;
1700+
for ( TableGroupJoin tableGroupJoin : parentTableGroup.getTableGroupJoins() ) {
1701+
if ( tableGroupJoin.getJoinedGroup().getModelPart() == this ) {
1702+
switch ( tableGroupJoin.getJoinType() ) {
1703+
case INNER:
1704+
// If this is an inner joins, it's fine if the paths match
1705+
// Since this inner join would filter the parent row anyway,
1706+
// it makes no sense to add another left join for this association
1707+
if ( tableGroupJoin.getNavigablePath().pathsMatch( fetchablePath ) ) {
1708+
return tableGroupJoin.getJoinedGroup();
1709+
}
1710+
break;
1711+
case LEFT:
1712+
// For an existing left join on the other hand which is row preserving,
1713+
// it is important to check if the predicate has user defined bits in it
1714+
// and only if it doesn't, we can reuse the join
1715+
if ( tableGroupJoin.getNavigablePath().pathsMatch( fetchablePath )
1716+
&& isSimpleJoinPredicate( tableGroupJoin.getPredicate() ) ) {
1717+
leftJoined = tableGroupJoin.getJoinedGroup();
1718+
}
17151719
}
1720+
}
1721+
}
17161722

1717-
if ( leftJoined != null ) {
1718-
return leftJoined;
1719-
}
1723+
if ( leftJoined != null ) {
1724+
return leftJoined;
1725+
}
17201726

1721-
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
1722-
fetchablePath,
1723-
parentTableGroup,
1724-
resultVariable,
1725-
null,
1726-
joinType,
1727-
true,
1728-
false,
1729-
creationState.getSqlAstCreationState()
1730-
);
1731-
parentTableGroup.addTableGroupJoin( tableGroupJoin );
1732-
return tableGroupJoin.getJoinedGroup();
1733-
}
1734-
);
1727+
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
1728+
fetchablePath,
1729+
parentTableGroup,
1730+
resultVariable,
1731+
null,
1732+
joinType,
1733+
true,
1734+
false,
1735+
creationState.getSqlAstCreationState()
1736+
);
1737+
parentTableGroup.addTableGroupJoin( tableGroupJoin );
1738+
final TableGroup joinedGroup = tableGroupJoin.getJoinedGroup();
1739+
fromClauseAccess.registerTableGroup( fetchablePath, joinedGroup );
1740+
return joinedGroup;
1741+
}
17351742
}
17361743

17371744
private TableGroup createTableGroupForDelayedFetch(

0 commit comments

Comments
 (0)