-->
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.  [ 13 posts ] 
Author Message
 Post subject: Open Session In View and Session.close()?
PostPosted: Thu Apr 13, 2006 1:24 pm 
Beginner
Beginner

Joined: Thu Aug 19, 2004 2:33 pm
Posts: 30
Location: CA, USA
Hibernate version: 3.1.2

Java Version: 1.5.0_06

I'm taking a look at the Open Session In View code on the Wiki and in the Caveat Emptor application. I noticed that the Servlet Filter never calls session.close() in the Thread Local version. Is there a reason for this?

The Session javadoc for close() states " It is not strictly necessary to close() the Session but you must at least disconnect() it.".

The Filter Code I'm using is below. It's basically a copy of the code on the Wiki. I'm also using the Generic DAO pattern described on the wiki. That pattern says that no session management is needed in the DAOs.

Code:
  public void doFilter(ServletRequest request,
             ServletResponse response,
             FilterChain chain)
      throws IOException, ServletException {

    try {

      sf.getCurrentSession().beginTransaction();

      // Call the next filter (continue request processing)
      chain.doFilter(request, response);

      // Commit and cleanup
      sf.getCurrentSession().getTransaction().commit();

    } catch (StaleObjectStateException staleEx) {

      // Rollback, close everything, possibly compensate for any permanent
      // changes during the conversation, and finally restart business
      // conversation. Maybe give the user of the application a chance
      // to merge some of his work with fresh data... what you do here
      // depends on your applications design.
      throw staleEx;

    } catch (Throwable ex) {

      // Rollback only
      try {
        if (sf.getCurrentSession().getTransaction().isActive()) {

          sf.getCurrentSession().getTransaction().rollback();

        }
      } catch (Throwable rbEx) {
        LOG.log(Level.SEVERE,
            "Could not rollback transaction after exception!", rbEx);
      }

      // Let others handle it... maybe another interceptor for exceptions?
      throw new ServletException(ex);
    }
  }


My web.xml defines the filter as follows. I'm using dispatcher REQUEST to prevent include:jsp tags from invoking the filter again.

Code:
  <filter-mapping>
    <filter-name>HibernateSessionRequestFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>


Thanks!
Don


Top
 Profile  
 
 Post subject: Re: Open Session In View and Session.close()?
PostPosted: Fri Apr 14, 2006 2:31 am 
Newbie

Joined: Sat Nov 22, 2003 9:21 pm
Posts: 18
Location: Malaysia
The reason to not close a session, is to ensure the objects that are retrieved from the session are not detached.

Plus if we do not want to use "Open session pattern", we have to deal with reataching a detached object:
- Which object need to be attached if it has parent-child relationship?

We need to ensure cascade property is set up correctly and care must be taken when dealing with unidirectional object. I.e. A has getB() but B does not have getA(). This mean re-attach B does not make A to be persistent.

- How to reattach a detached object without causing any modified fields to be persisted upon transaction commit?

1. session.refresh() refresh the detached object from the database and make it persistent (Any modified fields will be refreshed);
2. session.update() causes the detached object to be persistent object and upon transaction commit, the database will be updated;
3. session.merge(), merge the changes, BUT, it is unclear whether it will update the database upon transaction commit and whether we can navigate the object graph.
Quote:
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".

The semantics of this method are defined by JSR-220.


Basically it says that the detached object will be persistent but not associated to the current session?

Does not persistent means:
Quote:
persistent: associated with a unique Session


Note: This is taken from
http://www.hibernate.org/hib_docs/v3/ap ... ang.Object)
http://www.hibernate.org/hib_docs/v3/ap ... ssion.html

IMHO, Open Session In View pattern is required instead of recommended for long conversation, or at least until the javadoc is updated.

There is a danger having a session opened for long period of time. The memory usage will keep increasing, because the object is never detached from the session. This means, session.evict() need to be called, or close and create a new session when it is clear to do so.

http://www.hibernate.org/hib_docs/v3/ap ... ang.Object)

And lastly, Session.disconnect() is required to free up jdbc connection to be used by other Thread.

Regards,
Edward


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 12:35 pm 
Beginner
Beginner

Joined: Thu Aug 19, 2004 2:33 pm
Posts: 30
Location: CA, USA
Thanks Edward,

In my case I'm doing a Session per Request. I don't need the session to span HTTP requests. In this scenario, I believe I want the session to be closed at the end of the Servlet Filter since leaving it open will cache things in memory and maintain the database connection.

Leaving the session open in the servlet won't guarentee that the next request that comes in will go to the same servlet thread and thus use the same session. Is this correct?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 12:59 pm 
Beginner
Beginner

Joined: Thu Aug 19, 2004 2:33 pm
Posts: 30
Location: CA, USA
Just as a follow up, my comment above is based partially on this paragraph from the Hibernate 3 docs:

Quote:
11.1.1. Unit of work

....

The most common pattern in a multi-user client/server application is session-per-request. In this model, a request from the client is send to the server (where the Hibernate persistence layer runs), a new Hibernate Session is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the session is flushed and closed. You would also use a single database transaction to serve the clients request, starting and committing it when you open and close the Session. The relationship between the two is one-to-one and this model is a perfect fit for many applications.

...


The Open Session In View pattern doesn't follow this. I understand from the previous reply that this is to keep from having to reattach objects, but since each servlet thread has it's own session you are not guarenteed that the next user request will get the session you previously used. Or am I missing something?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 2:09 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
http://hibernate.org/42.html
http://hibernate.org/43.html


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 2:30 pm 
Beginner
Beginner

Joined: Thu Aug 19, 2004 2:33 pm
Posts: 30
Location: CA, USA
I've read those, but my question (or confustion) is with why the Servlet Filter would leave the Session open once the page has been rendered.

43.html has the two sections below which talk about Session closing and Transactions but they don't explain why the Servlet Filter never closes the Session. When the filter ends, the view has been rendered and the db transaction closed. Why does it stop at that point and not close the session?

Quote:
Can I commit the transaction before rendering the view?

Apparently, though never promoted in Hibernate documentation, some developers are using a variation of this pattern that keeps the Session open until the view has been rendered, but commits the database transaction before rendering of the view. The consequences are the same as not keeping the Session open: lazy loading does not work outside of a database transaction. It doesn't matter if the Session is still open, it has no connection. Further confusion appears when this anti-pattern actually works, but simply because the auto-commit mode is actually in use. See Sessions and transactions for more information about transaction processing basics and why auto-commit mode is inappropriate.

Can I use two transactions in one Session?

Yes, this is actually a better implementation of this pattern. One database transaction is used to read and write data during the processing of the request event. The second database transaction is only used to read data, during rendering of the view. No modifications to objects are made at this point. Hence, database locks are released early in the first transaction, allowing better scalability, and the second transaction can possibly be optimized (e.g. some databases require read-only transaction settings for best cleanup after transaction commit). To use two transactions you need a more powerful interceptor than a simple servlet filter - AOP is a good choice. The JBoss Seam frameworks uses this model.


Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 14, 2006 7:32 pm 
Regular
Regular

Joined: Wed Jul 07, 2004 2:00 pm
Posts: 64
I've never used it, but your hibernate config file can include the property
hibernate.transaction.auto_close_session
which closes the session when the transaction commits or rolls back.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 15, 2006 12:31 am 
Newbie

Joined: Sat Nov 22, 2003 9:21 pm
Posts: 18
Location: Malaysia
You can guarantee to use the same session. I usually put the hibernate session inside HttpSession.

Regards,
Edward

dsm08873 wrote:
Just as a follow up, my comment above is based partially on this paragraph from the Hibernate 3 docs:

Quote:
11.1.1. Unit of work

....

The most common pattern in a multi-user client/server application is session-per-request. In this model, a request from the client is send to the server (where the Hibernate persistence layer runs), a new Hibernate Session is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the session is flushed and closed. You would also use a single database transaction to serve the clients request, starting and committing it when you open and close the Session. The relationship between the two is one-to-one and this model is a perfect fit for many applications.

...


The Open Session In View pattern doesn't follow this. I understand from the previous reply that this is to keep from having to reattach objects, but since each servlet thread has it's own session you are not guarenteed that the next user request will get the session you previously used. Or am I missing something?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 26, 2007 8:28 am 
Regular
Regular

Joined: Tue May 04, 2004 6:15 am
Posts: 51
What about a scenario where a request takes so long that the user makes another one, which obtains the Session from the HttpSession finishes earlier and disconnects the Session while the first one is still running.

e.g. A web page returns a list of results but only shows a sublist of them. The user then opens in a new tab every sublist. Some of them will most likely fail.

PS. Wow. I didn't notice the year of that post. Sat Apr 15, 2006.

_________________
eu:life
http://www.eulife.gr


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 02, 2007 12:54 pm 
Beginner
Beginner

Joined: Thu Aug 19, 2004 2:33 pm
Posts: 30
Location: CA, USA
I think that would be a problem as well. The servlet code would have to somehow handle knowing when to close the session if multiple requests come in. I'm not using that pattern in my apps so I don't have any direct experience with it.

Don


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 02, 2007 12:57 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
You need to synchronize concurrent threads accessing non-threadsafe data in the HttpSession. This is the same issue with any web application and there are various solutions you can find with Google. JBoss Seam has a built-in locking mechanism for that.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject: Yes but...
PostPosted: Thu May 29, 2008 4:24 pm 
Newbie

Joined: Thu Jan 11, 2007 5:29 am
Posts: 2
But if you just create a series of API's that:

1) open hibernate session
2) map hibernate objects to business objects (or vice versa)
3) Save if necessary
4) close hibernate session

You might open and close hibernate sessions several times per request, but the shorter hibernate session lifecycles seem to scale better (at the expense of being a little slower) and gives you complete control over hibernates behavior (like problems with saving a parent object and having children object attributes being saved as well).


Top
 Profile  
 
 Post subject: Re: Yes but...
PostPosted: Mon Jun 09, 2008 9:46 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
jmanico wrote:
But if you just create a series of API's that:

1) open hibernate session
2) map hibernate objects to business objects (or vice versa)
3) Save if necessary
4) close hibernate session
.


Yes, but reattaching the detached instances can be a real pain. And a flury of transactions can put a nasty load on your database. You need to be careful.

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 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.