-->
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.  [ 3 posts ] 
Author Message
 Post subject: Concurrent finds / Collection flushing problem
PostPosted: Wed Jan 05, 2005 7:23 am 
Newbie

Joined: Wed Jan 05, 2005 6:54 am
Posts: 15
Hi,

I am using Hibernate in a tomcat environment, using a filter to open and close my ThreadLocal hibernate sessions.

My root problem is an "Illegal attempt to associate a collection with two open sessions" that has been discussed here in detail. But I did not find any solutions.

What I am doing is:

1. Starting a request to find a list of objects
2. Starting a second request to find the same list

In Summary: I am doing the same thing concurrently but an exception occurs in one case.

What I understood so far (debugging):
As every request obtains an own Thread and therefore an own Session, there are of course 2 sessions at the same time dealing with the same find statement.
On every find Hibernate now, i assume, does a flush and therefore tries to reassociate collections that just have been opened by another session that has not been closed yet. And this is it.

What I do not understand is, why this error occurs. I do not associate one collection with two sessions. Hibernate seems to do it. But somehow I am sure that this is not bug, but my fault ;-)

Has anybody some useful hint where I could solve this problem?

Thanks in advance,

Pvblivs


Top
 Profile  
 
 Post subject: Re: Concurrent finds / Collection flushing problem
PostPosted: Thu Jan 06, 2005 4:54 am 
Newbie

Joined: Wed Jan 05, 2005 6:54 am
Posts: 15
I think I solved this issue.

For any user who experiences such problem: NEVER share hibernate objects. NEVER store them into http sessions to reuse them later! ALWAYS clone them somehow if you try to reuse objects (e.g. the current user, what was my fault) or - more simply: just store an id in order to reload it (what might be a performance issue...).

If you use the ThreadLocal pattern for sessions (and only use one session per thread) it is always a safe solution to store hibernate objects in some thread context (e.g. http requests or ThreadLocal singletons).

This can neither be said too often nor explained too deeply! :-)

Thanks for reading my monlogue ;-)

Pvblivs


Top
 Profile  
 
 Post subject: Preventing errors from shared objects through synchronizing
PostPosted: Thu Jan 06, 2005 7:43 am 
Newbie

Joined: Wed Jan 05, 2005 6:54 am
Posts: 15
Hi there,

for anyone who is interested, here another solution how one can share hibernate objects within http sessions without hibernate exceptions. It should prevent threads from concurring on hibernate objects in http sessions.

The following code could be placed in a Filter responsible for opening and closing hibernate sessions in tomcat apps.

Regards,

Pvblivs



Code:
   private void doFilterHibernate(ServletRequest request, ServletResponse response, FilterChain chain)
         throws IOException, ServletException {
      // before processing filter chain:
      // create a hibernate session and open a jdbc connection
      // (in some cases, jdbc connections may not be needed:
      // switch lazyDatabase to true)
      try {
         HibernateUtil.getInstance().createSession();
         if (!lazyDatabase)
            HibernateUtil.getInstance().currentSession();
      } catch (DatabaseException e) {
         LOG.fatal("Error creating hibernate session", e);
      }
      try {
         // process filter chain
         chain.doFilter(request, response);
      } finally {
         // after processing filter chain:
         // close the current hibernate session
         // (an underlying jdbc connection will be closed as well
         // if it has been opened)
         try {
            HibernateUtil.getInstance().closeSession();
         } catch (DatabaseException e) {
            LOG.fatal("Error closing hibernate session", e);
         }
      }
   }

   /**
    * Processes the filtering for http requests. If configured,
    * further filtering is synchronized according to the current session.
    * That means that, for one user (represented through a http session) only
    * one http request is processed at the same time.
    *
    * Only one jdbc connection can be open per user if synchronized.
    *
    * @param request A HttpServletRequest containing the session that is to be synchronized.
    * @param response The HttpServletResponse object.
    * @param chain The FilterChain object.
    * @throws IOException
    * @throws ServletException
    */
   public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException,
         ServletException {
      if (synchronizeUserSession) {
         HttpSession session = request.getSession();
         synchronized(session) {
            doFilterHibernate(request, response, chain);
         }
      } else {
         doFilterHibernate(request, response, chain);
      }
   }

   /* (non-Javadoc)
    * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
    */
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
         ServletException {
      // no synchronization needed as no http session exists
      doFilterHibernate(request, response, chain);
   }


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