Closed
Description
Using a Fetch Join mapping for an entity that contains references to entities of the same type results in incorrect joins in SQL query.
For an entity:
public class Entity
{
public virtual ulong? EntityId { get; set; }
public virtual string EntityNumber { get; set; }
public virtual Entity ReferencedEntity { get; set; }
public virtual Entity AdditionalEntity { get; set; }
public virtual Entity SourceEntity { get; set; }
}
and mapping:
mapper.Class<Entity>(m =>
{
m.Id(c => c.EntityId, id =>
{
id.Generator(Generators.Native);
});
m.Property(c => c.EntityNumber);
m.ManyToOne(c => c.ReferencedEntity, p =>
{
p.Column("ReferencedEntityId");
p.Fetch(FetchKind.Join);
});
m.ManyToOne(c => c.AdditionalEntity, p =>
{
p.Column("AdditionalEntityId");
p.Fetch(FetchKind.Join);
});
m.ManyToOne(c => c.SourceEntity, p =>
{
p.Column("SourceEntityId");
p.Fetch(FetchKind.Join);
});
});
running the following query:
session
.QueryOver<Entity>()
.Where(e => e.EntityId == 1)
.List();
results in an incorrect SQL:
SELECT
this_.EntityId as entityid1_0_3_,
this_.EntityNumber as entitynumber2_0_3_,
this_.ReferencedEntityId as referencedentityid3_0_3_,
this_.AdditionalEntityId as additionalentityid4_0_3_,
this_.SourceEntityId as sourceentityid5_0_3_,
entity2_.EntityId as entityid1_0_0_,
entity2_.EntityNumber as entitynumber2_0_0_,
entity2_.ReferencedEntityId as referencedentityid3_0_0_,
entity2_.AdditionalEntityId as additionalentityid4_0_0_,
entity2_.SourceEntityId as sourceentityid5_0_0_,
entity3_.EntityId as entityid1_0_1_,
entity3_.EntityNumber as entitynumber2_0_1_,
entity3_.ReferencedEntityId as referencedentityid3_0_1_,
entity3_.AdditionalEntityId as additionalentityid4_0_1_,
entity3_.SourceEntityId as sourceentityid5_0_1_,
entity4_.EntityId as entityid1_0_2_,
entity4_.EntityNumber as entitynumber2_0_2_,
entity4_.ReferencedEntityId as referencedentityid3_0_2_,
entity4_.AdditionalEntityId as additionalentityid4_0_2_,
entity4_.SourceEntityId as sourceentityid5_0_2_
FROM
Entity this_
left outer join
Entity entity2_
on this_.ReferencedEntityId=entity2_.EntityId
left outer join
Entity entity3_
on entity2_.AdditionalEntityId=entity3_.EntityId
left outer join
Entity entity4_
on entity3_.SourceEntityId=entity4_.EntityId
WHERE
this_.EntityId = :p0;
entity3_ is joined to entity2_ and entity4_ is joined to entity3_ while both should be joined to this_ like entity2_.
Explicitly fetching referenced entities:
session
.QueryOver<Entity>()
.Where(e => e.EntityId == 1)
.Fetch(SelectMode.Fetch,
e => e.ReferencedEntity,
e => e.AdditionalEntity,
e => e.SourceEntity)
.List();
adds correct joins to SQL but previous still remain (entity3_ and entity4_):
SELECT
this_.EntityId as entityid1_0_5_,
this_.EntityNumber as entitynumber2_0_5_,
this_.ReferencedEntityId as referencedentityid3_0_5_,
this_.AdditionalEntityId as additionalentityid4_0_5_,
this_.SourceEntityId as sourceentityid5_0_5_,
entity2_.EntityId as entityid1_0_0_,
entity2_.EntityNumber as entitynumber2_0_0_,
entity2_.ReferencedEntityId as referencedentityid3_0_0_,
entity2_.AdditionalEntityId as additionalentityid4_0_0_,
entity2_.SourceEntityId as sourceentityid5_0_0_,
entity3_.EntityId as entityid1_0_1_,
entity3_.EntityNumber as entitynumber2_0_1_,
entity3_.ReferencedEntityId as referencedentityid3_0_1_,
entity3_.AdditionalEntityId as additionalentityid4_0_1_,
entity3_.SourceEntityId as sourceentityid5_0_1_,
entity4_.EntityId as entityid1_0_2_,
entity4_.EntityNumber as entitynumber2_0_2_,
entity4_.ReferencedEntityId as referencedentityid3_0_2_,
entity4_.AdditionalEntityId as additionalentityid4_0_2_,
entity4_.SourceEntityId as sourceentityid5_0_2_,
entity5_.EntityId as entityid1_0_3_,
entity5_.EntityNumber as entitynumber2_0_3_,
entity5_.ReferencedEntityId as referencedentityid3_0_3_,
entity5_.AdditionalEntityId as additionalentityid4_0_3_,
entity5_.SourceEntityId as sourceentityid5_0_3_,
entity6_.EntityId as entityid1_0_4_,
entity6_.EntityNumber as entitynumber2_0_4_,
entity6_.ReferencedEntityId as referencedentityid3_0_4_,
entity6_.AdditionalEntityId as additionalentityid4_0_4_,
entity6_.SourceEntityId as sourceentityid5_0_4_
FROM
Entity this_
left outer join
Entity entity2_
on this_.ReferencedEntityId=entity2_.EntityId
left outer join
Entity entity3_
on entity2_.AdditionalEntityId=entity3_.EntityId
left outer join
Entity entity4_
on entity3_.SourceEntityId=entity4_.EntityId
left outer join
Entity entity5_
on this_.AdditionalEntityId=entity5_.EntityId
left outer join
Entity entity6_
on this_.SourceEntityId=entity6_.EntityId
WHERE
this_.EntityId = :p0;