HHH-17838 @OneToOne relationship + @Embeddable keys + FetchType.LAZY fail

This commit is contained in:
Andrea Boriero 2024-10-22 16:03:28 +02:00 committed by Steve Ebersole
parent 406ab5bd4f
commit 2a70f069ad
1 changed files with 29 additions and 11 deletions

View File

@ -1553,7 +1553,19 @@ public class ToOneAttributeMapping
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) 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)
*/ */
if ( fetchTiming == FetchTiming.IMMEDIATE && selected ) {
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
final ForeignKeyDescriptor.Nature side;
if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
// If we are currently resolving the key part of a foreign key we do not want to add joins.
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
side = ForeignKeyDescriptor.Nature.KEY;
}
else {
side = this.sideNature;
}
if ( ( fetchTiming == FetchTiming.IMMEDIATE && selected ) || needsJoinFetch( side ) ) {
final TableGroup tableGroup = determineTableGroupForFetch( final TableGroup tableGroup = determineTableGroupForFetch(
fetchablePath, fetchablePath,
fetchParent, fetchParent,
@ -1631,16 +1643,6 @@ public class ToOneAttributeMapping
*/ */
final ForeignKeyDescriptor.Nature resolvingKeySideOfForeignKey = creationState.getCurrentlyResolvingForeignKeyPart();
final ForeignKeyDescriptor.Nature side;
if ( resolvingKeySideOfForeignKey == ForeignKeyDescriptor.Nature.KEY && this.sideNature == ForeignKeyDescriptor.Nature.TARGET ) {
// If we are currently resolving the key part of a foreign key we do not want to add joins.
// So if the lhs of this association is the target of the FK, we have to use the KEY part to avoid a join
side = ForeignKeyDescriptor.Nature.KEY;
}
else {
side = this.sideNature;
}
final DomainResult<?> keyResult; final DomainResult<?> keyResult;
if ( side == ForeignKeyDescriptor.Nature.KEY ) { if ( side == ForeignKeyDescriptor.Nature.KEY ) {
final TableGroup tableGroup = sideNature == ForeignKeyDescriptor.Nature.KEY final TableGroup tableGroup = sideNature == ForeignKeyDescriptor.Nature.KEY
@ -1692,6 +1694,22 @@ public class ToOneAttributeMapping
); );
} }
private boolean needsJoinFetch(ForeignKeyDescriptor.Nature side) {
if ( side == ForeignKeyDescriptor.Nature.TARGET ) {
// The target model part doesn't correspond to the identifier of the target entity mapping
// so we must eagerly fetch with a join (subselect would still cause problems).
final EntityIdentifierMapping identifier = entityMappingType.getIdentifierMapping();
final ValuedModelPart targetPart = foreignKeyDescriptor.getTargetPart();
if ( identifier != targetPart ) {
// If the identifier and the target part of the same class, we can preserve laziness as deferred loading will still work
return identifier.getExpressibleJavaType().getJavaTypeClass() != targetPart.getExpressibleJavaType()
.getJavaTypeClass();
}
}
return false;
}
private boolean isAffectedByEnabledFilters(DomainResultCreationState creationState) { private boolean isAffectedByEnabledFilters(DomainResultCreationState creationState) {
final LoadQueryInfluencers loadQueryInfluencers = creationState.getSqlAstCreationState() final LoadQueryInfluencers loadQueryInfluencers = creationState.getSqlAstCreationState()
.getLoadQueryInfluencers(); .getLoadQueryInfluencers();