January 30th, 2008

I've been working with NHibernate and ASP.NET and I've found quite some troubles to get NHibernate to work the way I wanted. We have an abstraction layer on top of NHibernate that hides the NHibernate intrinsics. With this abstraction layer we handle all the persistance for the domain entities.

The problem comes with the NHibernate session handling. We open a session per request (if needed) and we may store some entities in ASP.NET Session, Cache or Application. Basically, the problems present them selfs when we obtain an object with some NHibernate session, and later on we try to handle that object after the owning session has been closed. Example: put some object in Cache and try to access some collections later on.

Changing the current NHibernate session for an object proved to be quite troublesome (or... I really missed the best way to do it). We detected two scenarios where we needed to update the session for an NHibernate mapped class:

When we had an NHibernate proxy with a closed session

When we had the object, with some uninitialized NHibernate bags/sets/whatever - in this case we can work with the object, but we'll get an error when we try to access an uninitialized collection

These two scenarios will present the calling code with the following exception: Could not initialize proxy - the owning Session was closed.

I really, really searched the web to find some answers, but I got nothing. The NHibernate documentation suggests the use NHibernateUtil.Initialize to handle this problem, but this method assumes that the session's still available - and that may not be true.

// hack to force NHibernate to associate the new session with the given entity

session.Update(entity);

}catch{

if(session != null){

session.Dispose();

}

throw;

}

}

This will solve the lazy initialization issue, but it may bring some extra problems if you change the objects and don't update/flush. You may get an NHibernate exception if you try to associate a dirty object to a new session, or you may get some troubles with transaction related logic.

this should be taken care by your container. jboss deals with this by means of transactions. a section is opened when a business call is created, and is destroyed as soon as the business call is closed. a transaction is closed too

I never did cache by myself with NHibernate, I’ve used a second-level NHibernate cache, that shares data between sessions (as long as sessions were created by the same SessionFactory). This could be used with ASP.NET cache or other cache providers and seems to make caches/session management transparent to the programmer.

Have I missed your point again? :p
Probably yes… I’m not any NHibernate expert.

I used to have problems with the session handling as well, but now I’m using Spring.Net’s HibernateTemplate and OSIV so it’s no problem for me anymore. Also there is tons of posts on Spring.Net’s user forum regarding these problems, take a look at:http://forum.springframework.net/forumdisplay.php?f=15

Whenever I have a detached object and want to attach it to a new session (e.g when it comes back to the server), I simply use: session.Lock(entity, LockMode.Read); This is how the NHibernate documentation recommends reattachment if you haven’t modified the entity. If you have modified it, then session.update will reattach the entity and synchronize the changes into the new session. When you flush the session these changes will go into the DB.

Take a look at the Spring.Net NHibernate forum, there is a lot of discussions, tips and recommendations on how to solve these common issues.

[...] code is very slow. Some time ago, I had to go into NHibernate source code to understand how I could use sessions with ASP.NET, and I noticed that NHibernate uses a lot of internal objects. Well, on this case, I am fetching a [...]

I’m kind of new to NHibernate and was wondering if someone could shed some light on the behavior that I’m experiencing as well as a possible solution.

I have an NHibernate entity called User which upon login of my ASP.NET app, if valid, i retrieve and store in asp.net session. If null, I throw them back to the login page, etc…

Well, on this User object there are some other associations that I want to traverse later on subsequent http requests but I get the exception as the proxy’s are no longer associated with the active session.

(example: accessing User.UserCompanies[0].Company.Name will cause LazyInitializationException with no session associated)

What is the best way to make these proxy’s “alive” again without forcing them to actually initialize? I’m using the Session-Per-Request pattern. I’d prefer not having to re-get the User based on ID each request but am open to the most efficient solution.

About the Blog

Hello, I'm Pedro Santos and I'm the author of this blog. This blog is
mainly about gamedev and software development.
If you wish, you can subscribe to my feed or contact me.