Join fetch with Stateless Session

809 views
Skip to first unread message

CSharper

unread,
Dec 31, 2011, 1:20:24 AM12/31/11
to nhibernate-development
Hi,

I was experimenting a little with the stateless session and the next
SQL Server version (will follow in a separate post).

I found that when eager fetching entities like this...
using (var session =
sessionFactory.OpenStatelessSession())
using (var transaction = session.BeginTransaction())
{
var list = session.Query<Order>()
.FetchMany(a => a.OrderLines)
.ThenFetch(p => p.Product).ToList();
Assert.AreEqual(2, list.Count(a => a.OrderLines
.Any(p => p.Product.Name.Contains("soft"))));
}

... I get too many aggregate roots in the result, there are duplicate
instances for the same entity. For the stateless session it might be
even more important that the join fetch works as expected because lazy
loading is disabled for it.

With a small modification that would be fixed without the need to use
some result transformers. The stateless session uses a temporary
stateful persistence context and while a Query we could use its
already loaded entities to maintain the object identity thus
deduplicating the result. After the query is finished, the persistence
context is cleared so there is side effect for later queries. I've run
the NHibernate.Test unit tests and they work fine except for those
that have been red on my machine before the change.

As I am not experienced yet with the development process, I just post
the patch and somebody can tell me what to do or take on the hands on
his/her own. Is somebody interested in following that patch?

The patch in StatelessSessionImpl.cs is as follows:
@@ -449,11 +449,17 @@ namespace NHibernate.Impl
}

public override object GetEntityUsingInterceptor(EntityKey key)
{
CheckAndUpdateSessionStatus();
- return null;
+ // while a pending Query we should use existing temporary
entities so a join fetch does not create multiple instances
+ // of the same parent item
+ object obj;
+ if
(temporaryPersistenceContext.EntitiesByKey.TryGetValue(key, out obj))
+ return obj;
+ else
+ return null;
}

public override IPersistenceContext PersistenceContext
{
get { return temporaryPersistenceContext; }

CSharper

unread,
Jan 10, 2012, 3:20:49 PM1/10/12
to nhibernate-development
I've now created a pull request for this change:
https://github.com/nhibernate/nhibernate-core/pull/50

CSharper

unread,
Feb 16, 2012, 4:25:32 PM2/16/12
to nhibernate-development
Anybody using the Stateless Session? I see that change as a quick win.

I don't complain about the lack of feedback on this post but I am just
curious if a remarkable amount of NHibernate developers use the
Stateless Session and for which use cases it is used.
Is it usually only used for write-only actions?
How do people deal with situations where multiple related entity
classes should be read? (I think the join fetch is ideal for many
cases, isn't it?) Are result transformers used in this case to build
the distinct root entity list?


On 10 Jan., 21:20, CSharper <csharper2...@googlemail.com> wrote:
> I've now created a pull request for this change:https://github.com/nhibernate/nhibernate-core/pull/50
>
> On 31 Dez. 2011, 07:20, CSharper <csharper2...@googlemail.com> wrote:
>
>
>
>
>
>
>
> > Hi,
>
> > I was experimenting a little with thestatelesssession and the next
> > SQL Server version (will follow in a separate post).
>
> > I found that when eager fetching entities like this...
> >             using (var session =
> > sessionFactory.OpenStatelessSession())
> >             using (var transaction = session.BeginTransaction())
> >             {
> >                 var list = session.Query<Order>()
> >                     .FetchMany(a => a.OrderLines)
> >                     .ThenFetch(p => p.Product).ToList();
> >                 Assert.AreEqual(2, list.Count(a => a.OrderLines
> >                     .Any(p => p.Product.Name.Contains("soft"))));
> >             }
>
> > ... I get too many aggregate roots in the result, there are duplicate
> > instances for the same entity. For thestatelesssession it might be
> > even more important that the join fetch works as expected because lazy
> > loading is disabled for it.
>
> > With a small modification that would be fixed without the need to use
> > some result transformers. Thestatelesssession uses a temporary

Rory Plaire

unread,
Feb 16, 2012, 5:21:51 PM2/16/12
to nhibernate-...@googlegroups.com
I use it, but only for importing data.
 
In the cases where I need to lookup existing data in order to make relationships, I have to perform extra queries to get that data, or in some cases, I persist it in caches so I don't have to round trip back to the database. But outside of this, the stateless session is way too limited for normal querying and fetching related entities, as it should be, since it's main function is to get a lot of data into the database quickly and without using all the memory.
 
-r

Reply all
Reply to author
Forward
0 new messages