diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index 27ff73d98a..d905bb9f70 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -299,7 +299,7 @@ public class ToOneAttributeMapping } public boolean canJoinForeignKey(EntityIdentifierMapping identifierMapping) { - return isKeyReferringSide && identifierMapping == getForeignKeyDescriptor().getTargetPart(); + return isKeyReferringSide && identifierMapping == getForeignKeyDescriptor().getTargetPart() && !isNullable; } public String getReferencedPropertyName() { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java index fc61c215b4..81cdaa384a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java @@ -57,7 +57,7 @@ public class LazyTableGroup extends AbstractColumnReferenceQualifier implements return tableGroup; } - private TableGroup getTableGroup() { + public TableGroup getTableGroup() { if ( tableGroup != null ) { return tableGroup; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java index b5236e79d2..9ccbca00ee 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java @@ -129,6 +129,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces if ( existing.getNavigablePath().equals( navigablePath ) && fetchedModelPart.getNavigableRole() .equals( existing.getInitializedPart().getNavigableRole() ) ) { + assert fetchedModelPart == existing.getInitializedPart(); return existing; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java index 55c4fd3b67..42eba13aae 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityResultGraphNode.java @@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.persister.entity.AbstractEntityPersister; import org.hibernate.query.EntityIdentifierNavigablePath; import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.tree.from.LazyTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.results.graph.AbstractFetchParent; import org.hibernate.sql.results.graph.DomainResult; @@ -73,15 +74,27 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent identifierResult = null; visitIdentifierMapping( identifierNavigablePath, creationState, identifierMapping, entityTableGroup ); } - else if ( referencedModelPart instanceof ToOneAttributeMapping - && ( (ToOneAttributeMapping) referencedModelPart ).canJoinForeignKey( identifierMapping ) ) { + else if ( referencedModelPart instanceof ToOneAttributeMapping ) { // If we don't do this here, LazyTableGroup#getTableReferenceInternal would have to use the target table in case {id} is encountered - identifierResult = ( (ToOneAttributeMapping) referencedModelPart ).getForeignKeyDescriptor().createDomainResult( - navigablePath, - creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( navigablePath.getParent() ), - null, - creationState - ); + if ( ( (ToOneAttributeMapping) referencedModelPart ).canJoinForeignKey( identifierMapping ) ) { + identifierResult = ( (ToOneAttributeMapping) referencedModelPart ).getForeignKeyDescriptor() + .createDomainResult( + navigablePath, + creationState.getSqlAstCreationState() + .getFromClauseAccess() + .findTableGroup( navigablePath.getParent() ), + creationState + ); + + } + else { + identifierResult = identifierMapping.createDomainResult( + identifierNavigablePath, + ( (LazyTableGroup) entityTableGroup ).getTableGroup(), + null, + creationState + ); + } } else { identifierResult = identifierMapping.createDomainResult( @@ -144,7 +157,7 @@ public abstract class AbstractEntityResultGraphNode extends AbstractFetchParent attributeMapping -> { if ( attributeMapping instanceof ToOneAttributeMapping ) { ( (ToOneAttributeMapping) attributeMapping ).getForeignKeyDescriptor().createDomainResult( - navigablePath, + navigablePath.getParent(), entityTableGroup, null, creationState diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/cid/keymanytoone/association/EagerKeyManyToOneTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/cid/keymanytoone/association/EagerKeyManyToOneTest.java index d368f4b94e..681e28251c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/cid/keymanytoone/association/EagerKeyManyToOneTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/cid/keymanytoone/association/EagerKeyManyToOneTest.java @@ -64,6 +64,48 @@ public class EagerKeyManyToOneTest { scope.inTransaction( session -> { try { + /* + select + card0_.id as id1_0_0_, + card0_.field_card_id as field_ca2_0_0_, + card0_."field_key_id" as field_ke3_0_0_, + cardfield1_.card_id as card_id1_1_1_, + cardfield1_."key_id" as key_id2_1_1_, + card2_.id as id1_0_2_, + card2_.field_card_id as field_ca2_0_2_, + card2_."field_key_id" as field_ke3_0_2_, + key3_.id as id1_2_3_ + from + Card card0_ + left outer join + CardField cardfield1_ + on card0_.field_card_id=cardfield1_.card_id + and card0_."field_key_id"=cardfield1_."key_id" + left outer join + Card card2_ + on cardfield1_.card_id=card2_.id + left outer join + "key" key3_ + on cardfield1_."key_id"=key3_.id + where + card0_.id=? +11:08:42,367 TRACE BasicBinder:64 - binding parameter [1] as [VARCHAR] - [cardId] +11:08:42,370 TRACE BasicExtractor:60 - extracted value ([id1_0_2_] : [VARCHAR]) - [cardId] +11:08:42,370 TRACE BasicExtractor:60 - extracted value ([id1_2_3_] : [VARCHAR]) - [keyId] +11:08:42,370 TRACE BasicExtractor:60 - extracted value ([card_id1_1_1_] : [VARCHAR]) - [cardId] +11:08:42,370 TRACE BasicExtractor:60 - extracted value ([key_id2_1_1_] : [VARCHAR]) - [keyId] +11:08:42,371 TRACE BasicExtractor:60 - extracted value ([field_ca2_0_2_] : [VARCHAR]) - [cardId] +11:08:42,372 TRACE BasicExtractor:60 - extracted value ([field_ke3_0_2_] : [VARCHAR]) - [keyId] +11:08:42,372 DEBUG SQL:144 - + select + key0_.id as id1_2_0_ + from + "key" key0_ + where + key0_.id=? +11:08:42,372 TRACE BasicBinder:64 - binding parameter [1] as [VARCHAR] - [keyId] + + */ Card card = session.get( Card.class, CARD_ID ); CardField cf = card.getField();