views:

1105

answers:

4

I am implementing NHibernate into an existing web application. However, we have some other processes that do bulk inserting and updating on the database. How can I make NHibernate aware that changes are occurring on the backend db that were not initiated through NHibernate?

Most of the info that I have read around NHibernate use in asp.net have mentioned storing the Session object in the HttpContext or CallContext. This would then store the session object for the duration of the application lifecycle. This is what I have implemented. I was afraid of the costs of initializing NHibernate on each request. Isn't there a significant performance hit with this approach with initializing the Session object on each request?

Also, would it make more sense to store the SessionFactory in the the HttpContext or CallContext so that the mappings don't have to be regenerated on each request?

+1  A: 

The quick answer is a new session will see the new data. Can you clarify exactly what you expect to happen?

Do you want the saved entities to be aware that the data changed underneath them before saving?

Ben Scheirman
+11  A: 

You shouldn't. NHibernate sessions are there to help you work in an ACID environment, which means that one transaction is not aware of any concurrent transactions. You should be using short sessions which do small sets of actions. You should not be holding sessions open for long periods of time. If you do need long periods of time for working with domain objects, then you should be detaching and then re-attaching the domain objects from and to different sessions.

Once you open a new session, any changes done to the database before the session was opened will be made available through NHibernate.

Justice
+4  A: 

You should not store the Session over multiple requests. Bad, bad idea.

There is little to no overhead with recreating it on every call. It should use database connection pooling - which is where the bulk of the overhead would be.

TheSoftwareJedi
+3  A: 

By default NHibernate will not cache anything between sessions. If your sessions are short lived (per request), you shouldn't have much to worry about.

If you are using second level caching or query caching though, you may need to flush the cache manually. SessionFactory.Evict or SessionFactory.EvictQueries should help there. Restarting the app should also do it, but that's probably not the answer you're looking for.

In an ASP.NET app, the general usage I've seen is to create one SessionFactory for the app and create a new Session for each request.

The SessionFactory takes a while to initialize, is thread safe, and only needs to be initialized once.

The Sessions are not thread safe and are pretty quick to create.

Anything stored in the HttpContext will only be alive for the length of the request. Storing the session in the context is normal and should give you the desired result. The SessionFactory is usually stored in a static variable and will last as long as the app.

See the NHIbernateHelper class here for an example.

David Hogue
I know this is an oooold question but it's probably worth noting that if you're using an out-of-process 2nd level cache restarting the app won't clear it.
AlexCuse