Skip to content

Commit 8d39709

Browse files
committed
HHH-18330 Check model part when reusing table group for to-one fetch
1 parent c27ec0f commit 8d39709

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
@@ -1741,52 +1741,59 @@ private TableGroup determineTableGroupForFetch(
17411741
else {
17421742
joinType = null;
17431743
}
1744-
return fromClauseAccess.resolveTableGroup(
1745-
fetchablePath,
1746-
np -> {
1747-
// Try to reuse an existing join if possible,
1748-
// and note that we prefer reusing an inner over a left join,
1749-
// because a left join might stay uninitialized if unused
1750-
TableGroup leftJoined = null;
1751-
for ( TableGroupJoin tableGroupJoin : parentTableGroup.getTableGroupJoins() ) {
1752-
switch ( tableGroupJoin.getJoinType() ) {
1753-
case INNER:
1754-
// If this is an inner joins, it's fine if the paths match
1755-
// Since this inner join would filter the parent row anyway,
1756-
// it makes no sense to add another left join for this association
1757-
if ( tableGroupJoin.getNavigablePath().pathsMatch( np ) ) {
1758-
return tableGroupJoin.getJoinedGroup();
1759-
}
1760-
break;
1761-
case LEFT:
1762-
// For an existing left join on the other hand which is row preserving,
1763-
// it is important to check if the predicate has user defined bits in it
1764-
// and only if it doesn't, we can reuse the join
1765-
if ( tableGroupJoin.getNavigablePath().pathsMatch( np )
1766-
&& isSimpleJoinPredicate( tableGroupJoin.getPredicate() ) ) {
1767-
leftJoined = tableGroupJoin.getJoinedGroup();
1768-
}
1769-
}
1744+
final TableGroup existingTableGroup = fromClauseAccess.findTableGroupForGetOrCreate(
1745+
fetchablePath
1746+
);
1747+
if ( existingTableGroup != null && existingTableGroup.getModelPart() == this ) {
1748+
return existingTableGroup;
1749+
}
1750+
else {
1751+
// Try to reuse an existing join if possible,
1752+
// and note that we prefer reusing an inner over a left join,
1753+
// because a left join might stay uninitialized if unused
1754+
TableGroup leftJoined = null;
1755+
for ( TableGroupJoin tableGroupJoin : parentTableGroup.getTableGroupJoins() ) {
1756+
if ( tableGroupJoin.getJoinedGroup().getModelPart() == this ) {
1757+
switch ( tableGroupJoin.getJoinType() ) {
1758+
case INNER:
1759+
// If this is an inner joins, it's fine if the paths match
1760+
// Since this inner join would filter the parent row anyway,
1761+
// it makes no sense to add another left join for this association
1762+
if ( tableGroupJoin.getNavigablePath().pathsMatch( fetchablePath ) ) {
1763+
return tableGroupJoin.getJoinedGroup();
1764+
}
1765+
break;
1766+
case LEFT:
1767+
// For an existing left join on the other hand which is row preserving,
1768+
// it is important to check if the predicate has user defined bits in it
1769+
// and only if it doesn't, we can reuse the join
1770+
if ( tableGroupJoin.getNavigablePath().pathsMatch( fetchablePath )
1771+
&& isSimpleJoinPredicate( tableGroupJoin.getPredicate() ) ) {
1772+
leftJoined = tableGroupJoin.getJoinedGroup();
1773+
}
17701774
}
1775+
}
1776+
}
17711777

1772-
if ( leftJoined != null ) {
1773-
return leftJoined;
1774-
}
1778+
if ( leftJoined != null ) {
1779+
return leftJoined;
1780+
}
17751781

1776-
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
1777-
fetchablePath,
1778-
parentTableGroup,
1779-
resultVariable,
1780-
null,
1781-
joinType,
1782-
true,
1783-
false,
1784-
creationState.getSqlAstCreationState()
1785-
);
1786-
parentTableGroup.addTableGroupJoin( tableGroupJoin );
1787-
return tableGroupJoin.getJoinedGroup();
1788-
}
1789-
);
1782+
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
1783+
fetchablePath,
1784+
parentTableGroup,
1785+
resultVariable,
1786+
null,
1787+
joinType,
1788+
true,
1789+
false,
1790+
creationState.getSqlAstCreationState()
1791+
);
1792+
parentTableGroup.addTableGroupJoin( tableGroupJoin );
1793+
final TableGroup joinedGroup = tableGroupJoin.getJoinedGroup();
1794+
fromClauseAccess.registerTableGroup( fetchablePath, joinedGroup );
1795+
return joinedGroup;
1796+
}
17901797
}
17911798

17921799
private TableGroup createTableGroupForDelayedFetch(

0 commit comments

Comments
 (0)