-->
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.  [ 9 posts ] 
Author Message
 Post subject: HibernateFilter
PostPosted: Thu Nov 03, 2005 7:07 am 
Regular
Regular

Joined: Fri Sep 30, 2005 6:15 am
Posts: 50
Hi,
based on what I've read on Internet to handle the error on "open session", I have created the HibernateFilter with the code below...

Just two questions :
[1] How hibernate retrieve the good connection to close in that Filter as it can have many sessions opened?
[2] Is my design good enough? do you see some weakness compare to ohter filters? Is it enough robust for production environment?

Here is the interesting snippet needed to construct the HibernateFilter (It may help also some of us who wants a sample) :

Code:
[b][u]HibernateFilter.java[/u][/b]

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

      try {         

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

      } finally {
         // No matter what happens, close the Session.
         HibernateUtil.closeSession();
      }
   }

[b][u]MyStrutsAction.java[/u][/b]

         Session session = HibernateUtil.currentSession();
         Transaction transaction = session.beginTransaction();


        //The comp_id on contact is stupid but just for sample with composite keys!
   Query query = session.createQuery("from contact declarationsdsa where contact.comp_id.lastname=? and contact.comp_id.firstname=?");
   query.setString(0,"Dupont");
        query.setString(1,"Jean");

   Iterator it = query.iterate();
        Contact contact = null;
   if(it.hasNext()) {
          contact= (Contact) it.next();
   }
      
   request.setAttribute("contact",contact);
      
   transaction.commit(); //TODO handle rollback
   session.flush();

[b][u]web.xml[/u][/b]
   <!-- HibernateFilter -->   
   <filter>
       <filter-name>hibernateFilter</filter-name>
       <display-name>Hibernate Filter</display-name>
       <filter-class>org.mycompany.hibernate.HibernateFilter</filter-class>     
   </filter>
   
   <filter-mapping>
       <filter-name>hibernateFilter</filter-name>   
       <url-pattern>*.do</url-pattern>   
   </filter-mapping>


[b][u]MyJSP.java[/u][/b]

we can display contact.getComp_id().getLastname() without getting the error on "session and proxy"


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2005 5:10 pm 
Regular
Regular

Joined: Fri Sep 30, 2005 6:15 am
Posts: 50
So, nobody knows how hibernate retrieve the good session to close in the hibernateFilter among all opened sessions?

nobody want to earn a credit? ;o)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 03, 2005 11:42 pm 
Beginner
Beginner

Joined: Sat Oct 22, 2005 11:16 pm
Posts: 40
Your HibernateFilter should pick up the Session from the factory. It should then bind the filter BEFORE it chains to whatever is going to actually do the request. It needs to make the session available, perhaps by installing it as a request parameter, so that servlets behind the filter can get it that way.

You could combine your Hibernate Session filter with the authorization filter. Check to see that the user is in the HttpSession, then grab a Hibernate session, then constrain that session so that it can only see objects which the user owns, and THEN do the chain.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 4:41 am 
Regular
Regular

Joined: Fri Sep 30, 2005 6:15 am
Posts: 50
Thanks sleepybar!

So you mean that filter provided here (http://www.hibernate.org/43.html) is not sufficient to ensure that the good session is closed?

I do not understand all your steps cause i'm a newbie...do you have an url with a sample?

THANKS!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 10:17 am 
Expert
Expert

Joined: Mon Feb 14, 2005 12:32 pm
Posts: 609
Location: Atlanta, GA - USA
gaetmail wrote:
Thanks sleepybar!

So you mean that filter provided here (http://www.hibernate.org/43.html) is not sufficient to ensure that the good session is closed?

I do not understand all your steps cause i'm a newbie...do you have an url with a sample?

THANKS!


What do you mean by "good session" ?

In the examples using a Filter to ensure the Session is closed, the Session object is stored in a ThreadLocal so that the Session being closed is the same session that has been used along this Thread of execution.

In a managed environment (using JTA transactions) the sf.getCurrentSession() method uses ensure that you will always receive the correct Session.

Do you have an actual problem or are you just questioning the many people that use this pattern without issue for no particular reason ?

_________________
Preston

Please don't forget to give credit if/when you get helpful information.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 10:38 am 
Beginner
Beginner

Joined: Tue Jun 07, 2005 11:36 pm
Posts: 22
Small point - most of the examples point to using a javax.servlet.Filter to close any open session on the way out of the app. If you are using a somewhat new servlet container that supports the servlet 2.4 spec (JBoss 4 or Tomcat 5.5 standalone, maybe Tomcat 5.0?), you can use a javax.servlet.ServletRequestListener instead. To me, it just seems a little cleaner because it separates the coming in logic versus the going out logic.

My impl below, with some logging I had in to help figure out some threading issues. (Note that HibernateManager in the code is pretty much the same as the standard HibernateUtil).

Code:
/**
* Concept taken from: http://www.hibernate.org/43.html
* <p>
* A servlet request listener that opens and closes a Hibernate Session for each request. It
* guarantees a sane state, committing any pending database transaction once the request is going
* out of scope.
*
* @see com.osc.util.hibernate.HibernateManager
* @version $Revision: 1.2 $
* @author esword
*/
public class HibernateServletListener implements javax.servlet.ServletRequestListener
{
    protected static final Log log = Log.getLog(HibernateServletListener.class);

    private static int level = 0;

    public void requestInitialized(ServletRequestEvent arg0)
    {
        //log.debug(buildMessage("requestInitialized:\t" + Thread.currentThread().getName()));
        level++;
    }

    public void requestDestroyed(ServletRequestEvent arg0)
    {
        try
        {
            // Commit any pending database transaction.
            HibernateManager.closeSession();
        }
        catch (Throwable e)
        {
            log.error("Error committing.", e);
        }
        level--;
        //log.debug(buildMessage("requestDestroyed:\t" + Thread.currentThread().getName()));
    }

    /**
     * Hack method to help see levels of thread calls
     */
    protected String buildMessage(String msg)
    {
        // Don't create anything until actually needed
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < level; i++)
        {
            buf.append("  ");
        }
        buf.append(msg);
        return buf.toString();
    }
}


And then web.xml:

Code:
    <listener>
        <listener-class>com.osc.util.hibernate.HibernateServletListener</listener-class>
    </listener>


I believe this will do the same thing for you. It seems to work well for us. Someone else may know of any drawbacks to it.

-----
Eric

Helpful? Hit me with a credit!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 04, 2005 10:52 am 
Regular
Regular

Joined: Fri Sep 30, 2005 6:15 am
Posts: 50
pksiv wrote:
Do you have an actual problem or are you just questioning the many people that use this pattern without issue for no particular reason ?


yes I'm just wondering if my use of this pattern is sure because I want to use it in production and I wouldn't like to the bad surprise that the session corresponding to another request has been closed by error in my filter....

By "good session" I mean : the session I used in my struts action (i'm not using spring cause it's too complex). How do hibernate to retrieve this session in the filter?
Because in the filter, i just code "HibernateUtil.closeSession()"...then it does it jobs with threadlocal but I don't understand how it does to find the threadlocal corresponding to the session I opened in my struts action and that I want to close now in the filter?

Thanks for helping and sorry for my english..hope you'll understand


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 07, 2005 9:13 am 
Beginner
Beginner

Joined: Tue Jun 07, 2005 11:36 pm
Posts: 22
threadLocal does just what it's name implies - stores one value per thread. Think of it like a Map object. Normally, you give a map a key and a value. For a threadLocal variable, you just give it a value. It uses the id of the current thread as the key. Give it another value in another thread, and it stores a different key->value association. When you call threadLocal.get(), the thread in which you make the "get()" call determines what value you get back.

So how does this relate to what session is open and then closed? Each HTTP user request that comes in is handled on its own thread. So in your Struts action, when you call HibernateUtil.getSession(), a new key->value association is added to the sessions threadLocal variable. After your action has finished processing, the thread stack unwinds and just before a response is sent back to the user, the HibernateFilter is invoked which calls closeSession(). There is a one-to-one-to-one correspondence between a user request, a Struts action being called, and the filter being invoked. They all happen on the same thread, so you are guaranteed that the proper session will be closed. You won't accidentally kill a session started by another user request, because it's on another thread.

Make sense?

-----
Eric

Helpful? Hit me with a credit!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 07, 2005 10:00 am 
Regular
Regular

Joined: Fri Sep 30, 2005 6:15 am
Posts: 50
Thanks Eric!

What a good and detailled answer for a "newbie"! :o)

I've rated you as you answer exactly to my question and leran me one more thing!

THANKS!


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