Really need to see the mappings too. Best to raise a JIRA and attach a patch there.

Cheers,
   Richard

--------------------------------------------------
From: "Dan" <[email protected]>
Sent: Thursday, April 29, 2010 7:14 PM
To: "nhibernate-development" <[email protected]>
Subject: [nhibernate-development] Fetch joining doesn't always work with Future()

I found a repeatable scenario where Fetch Join isn't working.  I don't
know NHibernate well enough to troubleshoot exactly why it's
happening, but I was able to create a test in NHibernate.Tests that
triggers the issue.  Here's how I'm able to repeat it:

Say you you have 3 entities.  A root entity Policy has a 1-M to Tasks,
which has a M-1 to TeamMember.

class Policy
   int Id
   ISet<Task> Tasks

class Task
   int Id
   TeamMember TeamMember

Issue this query:
Policy p = s.CreateQuery("SELECT p FROM Policy p " +
"LEFT JOIN FETCH p.Tasks t " +
"WHERE p.Id = :id")
.SetParameter("id", p2.Id)
.FutureValue<Policy>().Value;

Then this one:
IEnumerable<Task> tasks = s.CreateQuery("SELECT t FROM Task t " +
"INNER JOIN FETCH t.TeamMember ")
.Future<Task>();

And this check will fail:
for each (Task t in tasks)
   Assert.IsTrue(NHibernateUtil.IsInitialized(t.TeamMember))

Not all TeamMember properties on the returned set of tasks will be
initialized.  They'll be uninitialized proxies.  Oddly enough, if I
comment out the first query, the 2nd one does exactly what I would
expect it to do.

Is there a reason this is happening, or did I run into an obscure bug?

Here's the method body of my failing test:




[Test]
public void TestDansWeirdScenario()
{
Policy p1, p2;
Task t1, t2;
TeamMember tm1, tm2;

using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
tm1 = new TeamMember() { Name = "Joe" };
tm2 = new TeamMember() { Name = "Bill" };

s.Save(tm1);
s.Save(tm2);

p1 = new Policy() { PolicyNumber = 5 };
p1.Tasks.Add(new Task() { Policy = p1, TaskName = "Call Customer",
TeamMember = tm1 });


p2 = new Policy() { PolicyNumber = 5 };
p1.Tasks.Add(new Task() { Policy = p2, TaskName = "Send Invoice",
TeamMember = tm2 });
p1.Tasks.Add(new Task() { Policy = p2, TaskName = "Something Else",
TeamMember = tm2 });

s.Save(p1);
s.Save(p2);

t.Commit();
}

using (ISession s = sessions.OpenSession())
using (ITransaction t = s.BeginTransaction())
{
Policy reloadP2 = s.CreateQuery("SELECT p FROM Policy p " +
"LEFT JOIN FETCH p.Tasks t " +
"WHERE p.Id = :id")
.SetParameter("id", p2.Id)
.FutureValue<Policy>().Value;

IEnumerable<Task> tasks = s.CreateQuery("SELECT t FROM Task t " +
"INNER JOIN FETCH t.TeamMember ")
.Future<Task>();

foreach (Task tsk in tasks)
{
Assert.IsTrue(NHibernateUtil.IsInitialized(tsk.TeamMember));
}
}
}

Reply via email to