-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: WinForm session management
PostPosted: Wed Jul 11, 2007 10:23 am 
Regular
Regular

Joined: Mon Oct 02, 2006 12:03 pm
Posts: 62
Hello forum, I'm developing a WinForm project with C#.NET and I'm using NHibernate. I've developed my project, but I want to improve it using lazy issue. My question is about session manement.

When I get a Entity I execute this template code:

Code:
public Model.Ubicacio getEntity (System.Int32 id)
      {
         NHibernate.ISession session = this.session_factory.OpenSession();
         NHibernate.ITransaction tx = session.BeginTransaction();

         Model.Entity entity = null;
         try
         {
            entity = (Model.Entity)session.Get(typeof(Model.Entity), id);
         }
         catch (System.Exception ex)
         {
            tx.Rollback();
         }
         finally
         {
            session.Close();
         }
         return ubicacio;
      }


However, I'm retrieving collection with lazy mode, and I can't close the session -->


Code:
public Model.Ubicacio getEntity (System.Int32 id)
      {
         NHibernate.ISession session = this.session_factory.OpenSession();
         NHibernate.ITransaction tx = session.BeginTransaction();

         Model.Entity entity = null;
         try
         {
            entity = (Model.Entity)session.Get(typeof(Model.Entity), id);
         }
         catch (System.Exception ex)
         {
            tx.Rollback();
         }
         finally
         {
            //session.Close();
         }
         return ubicacio;
      }


But I think that this isn't the correct solution. How would you design this? I've read about session manegament, but I find anything.

Concrete questions:

Does Open session means open a database connection?
While a session is openned implies a database connection is openned?
What's a transaction? Is it a database connection?

Thanks for all.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 2:58 pm 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi jeusdi!

Session object is not DBConnection - it just use DBConnection for it's internal purposes - so you may have many sessions that share single connection. And you can supply uor own connection for NHibernate... I believe that in common scenario (if you'll follow main NHibernate principle - make sessions lifesycle as short as possible) you just don't have to worry about DB connections - let NHibernate manage them for you.
Transactions are definetely not connections - they are a kind of wrappers for real DB transactions.

The real problem with your design - you try to "hide" NHiberanate by creating "absolutely generic" data access layer - I think you'd better create "absolutely specific" DAL - so that you would have as many data access methods, as many use cases you have - e.g. one will retreive "just customers whose name match criteria", other will retreive "specified customer, all it's orders and all it's order details" and so on. Basically you have to retreive all the objects (from huge objects graph) you need in your use case and close session - this way you can avoid LazyInitializationException, without turning off lazy loading...
At least it is my humble understanding of NHibernate "best practices for WinForms applications"...

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 6:40 pm 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
Quote:
Basically you have to retreive all the objects (from huge objects graph) you need in your use case and close session - this way you can avoid LazyInitializationException, without turning off lazy loading...


In general I agree with this approach, but sometimes your app can preform a lot better by avoiding loading those entities that are seldom needed in a use case (in one of our use cases we use lazy-loading to avoid preloading 25000 rows of profile data). Anyway, it isn't that hard to make lazy-loading happen quite invasive and automatic. You can read this thread to get some ideas for how this can be done.

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 6:20 am 
Beginner
Beginner

Joined: Tue Jul 10, 2007 5:27 am
Posts: 34
Location: Belgium
steinard wrote:
Quote:
Basically you have to retreive all the objects (from huge objects graph) you need in your use case and close session - this way you can avoid LazyInitializationException, without turning off lazy loading...


In general I agree with this approach, but sometimes your app can preform a lot better by avoiding loading those entities that are seldom needed in a use case (in one of our use cases we use lazy-loading to avoid preloading 25000 rows of profile data).


When you know you need the extra 25000 rows, you could also simply reattach your object to an nhibernate session, pull in the extra objects, and close the session again

_________________
Davy Brion
http://ralinx.wordpress.com


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 12, 2007 7:09 am 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
Quote:
When you know you need the extra 25000 rows, you could also simply reattach your object to an nhibernate session, pull in the extra objects, and close the session again


Sure, that's exactly what you would do if you use AOP, the only difference is that the code is written more abstract once and is resuable. Then you can easily remove all the tedious try-catches where you would initialize the callback to the middleware which would reattach your object with a new nhibernate session and pull in the extra objects. You do not have to change one single line of code in the service layer to allow for this. In the presentation model you end up with a simple attribute to allow for this above the method/property while the method is untouched and is not "polluted" with any infrastructural logic.

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 13, 2007 4:34 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi steinard!

But as I understand there are serious logical problems with such design (automatic reconnection and lazy accociated objects retreiving) - it is the case why there is no such functionality in NHibernate itself. So you have to take into account this consideration - it may be safe in one case, but will lead to great problems in other cases...

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 13, 2007 6:09 am 
Beginner
Beginner

Joined: Tue Jan 02, 2007 5:53 pm
Posts: 42
Location: Bergen, Norway
Hi Igork!

You are right when you are saying:
Quote:
- it may be safe in one case, but will lead to great problems in other cases...

Yes, and you should be careful about when you use it and what you use it for. But that does not mean that you should not use it or disable the ability to lazy-load. You would typically only decorate a few methods in your presentation model with the AOP attribute for starting an ad-hoc read.

Quote:
In which scenarios would you enable the autocommit mode in Hibernate, so that you can use a Session without beginning and ending a transaction manually? Systems that benefit from autocommit mode are systems that require on-demand (lazy) loading of data, in a particular Session and persistence context, but in which it is difficult to wrap transaction boundaries around all code that might trigger on-demand data retrieval. This is usually not the case in web applications that follow the design patterns we discuss in chapter 16. On the other hand, desktop applications that access the database tier through Hibernate often require on-demand loading without explicit transaction boundaries. For example, if you double-click on a node in a Java Swing tree view, all children of that node have to be loaded from the database. You'd have to wrap a transaction around this event manually; the autocommit mode is a more convenient solution.

Quote taken from here: http://www.hibernate.org/403.html

It is not Hibernates responsibility to tune your application for performance and using ad hoc transactions could be useful, but must be used with care. What NHibernate actually could help with is to bring more context information into the LazyInitializationException as the two classes that throws this exception has information about owning entity type and id, and sometimes even the entity object itself. I'm already doing this, you can read about it
here and here.

_________________
Cheers,
Steinar.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 13, 2007 12:30 pm 
Expert
Expert

Joined: Fri Oct 28, 2005 5:38 pm
Posts: 390
Location: Cedarburg, WI
In a windows environment where you have to consume detached entities that were fetched in a previous NHibernate session and are were not fully initialized by that previous session (because doing so would be horrendously expensive), we deal with it by always reattaching those entities to the current session before accessing any of their (potentially uninitialized) properties. In the general case you can run into problems where the session already fetched an entity with the same ID, and you have to merge differences in property values and change all your local references to the merged entity to the instance in the NHibernate session.

It's a hassle, but it seems to work for us so far. One example where we use it is in a windows treeview. Entities and their properties get associated with tree nodes, but the entities are not forced to initialize until the nodes are expanded. The initial NHibernate session that runs the query and populates the root nodes of the treeview is short lived, and no session exists during the "user think time". When the user expands a node (or otherwise performs some action), we create a new session, reattach the entities we need to deal with, and let any lazy loading happen as needed during entity manipulation. We then promptly close and dispose of the session.

We've also taken this approach for some service objects that live on web servers, that keep instances of rarely changed but heavily used entities. There are 1000's of entities to be cached, most are infrequently accessed, some are heavily accessed, and there's no way to know at compile time which ones get the heavy use. So, the service object queries the entities on startup but does not force initialization on them, and when the service processes requests, if any of the entities it needs to manipulate are uninitialized it creates a new session, attaches the entities, then closes and disposes the session as soon as it's done using the entities. All of the access must be done with thread-safe locking since the service gets hit by all requests coming into the web server.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.