Search code examples
sqlnhibernate

Why JoinAlias doesn't fetch a sub list


I have 2 objects, ExamType which has a list of Exams. I want with nhibernate to fetch an ExamType with its list of exams.

If I run this query:

session.QueryOver<Examtype>(() => examTypeAlias)
    .JoinAlias(e => e.Exams, () => examAlias)
    .Where(e => e.Id == 12345)
    .Future<Examtype>();

the generated SQL is

SELECT 
  examType.Id as id, 
  exam1.Id as examId, 
  exam1.ExamTypeId as examExamTypeId, 
FROM 
  Examtype examType 
  inner join Exam exam1 on examType.Id = exam1.ExamTypeId 
WHERE 
  examType.Id = 12345

and the problem is that the retrieved ExamType object will do a lazy load of exams.

Then if I run the query:

session.QueryOver<Examtype>(() => examTypeAlias)
    .Left.JoinAlias(e => e.Exams, () => examAlias)
    .Where(e => e.Id == 12345)
    .Future<Examtype>();

the generated SQL is

SELECT 
  examType.Id as id, 
  exam1.Id as examId1, 
  exam1.ExamTypeId as examExamTypeId1, 
  exam2.Id as examId2, 
  exam2.ExamTypeId as examExamTypeId2, 
FROM 
  Examtype examType 
  left outer join Exam exam1 on examType.Id = exam1.ExamTypeId 
WHERE 
  examType.Id = 12345

and this time, there is an eager loading of exams.

I don't understand why the second query generated twice the same columns of Exam and why in the first query where the join is inner, exams are not fetched as the SQL query result fetches all records.

Any idea?


Solution

  • I can't say why but that's default behavior - only left join collections are fetched in Criteria/QueryOver queries.

    Though in NHibernate 5.2+ you can enable fetching with additional Fetch(SelectMode.Fetch, () => examAlias) call:

    session.QueryOver<Examtype>(() => examTypeAlias)
        .JoinAlias(e => e.Exams, () => examAlias)
        .Fetch(SelectMode.Fetch, () => examAlias) //<-- Fetch provided aliases
        .Where(e => e.Id == 12345)
        .Future<Examtype>();
    

    See https://github.com/nhibernate/nhibernate-core/pull/1599 for all SelectMode options explained.