Announcement Announcement Module
Collapse
No announcement yet.
Hibernate and Lazy Loading. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate and Lazy Loading.

    Heres the situation :
    Hibernate mapped pojos displayed on the front end via JSF. The backing beans use TransactionalServices to access the data, and store off into the session (as they will be edited on front via many operations, then finally saved). And i'm using OpenSessionInView to keep the session open for lazy loading during the view rendering.

    So the problem comes in when the request comes back to the server and JSF attempts to update the models (Pojo's). If it hits anything that needs to be lazy loaded, it fails.

    Now at one point I had a long running session that was added to the session, the issue comes in that i had to locate the session, and reconnect before JSF touched any of the pojo's to ensure that lazy init works. That was problematic as there were no good places to hook in that functionality (using webflows and jsf isnt a seemless integration).

    So I attempted to try using disconnected objects, but now i have issues where i need to reconnect objects, but again there isnt a good place to do it, as the JSF code happens outside of the webflow process.

    Ideally it seems like the Pojo's need to have an intercetor that re-associates them with a readonly session if there not already in a session so that they can load data.

    Or possibly have an interceptor that hooks into and detects that a lazy load condition and defers that off to a handler that ensures there is a session to lazy load against

  • #2
    Hi,
    I see two options:

    1. Long running Hibernate sessions: implemet a filter that takes care of session lookup + flush + other details:
    Code:
    public class LongRunningHibernateSessionFilter extends OncePerRequestFilter {
    
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    			throws ServletException, IOException {
     //looks up the session from the HTTP session 
     Session session = lookupSession(request);
     if(session == null){
           //create a new Hibernate session and stopre it in the HTTP session
           session = createSession();
      }
      session.connect();
      if (!TransactionSynchronizationManager.hasResource(sessionFactory)) {
    	TransactionSynchronizationManager.bindResource(sessionFactory,  new SessionHolder(session));
    	}
    
      filterChain.doFilter(request, response);
      //flush the changes to the database
      session.flush();
      session.disconnect();
    }
    Maybe you might want to change/adjust when the Hibernate session is flushed according to your use cases. Also, it would make sense to have a HttpSessionListener that creates and destroys the Hibernate session.

    2. Hibernate session per request + OpenSessionInViewFilter + reatach objects filter:
    Code:
    public class ReatachFilter extends OncePerRequestFilter {
    
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    			throws ServletException, IOException {
      Session session = lookupSession();
      Enumeration en = request.getSession().getAttributeNames();
      while (en.hasMoreElements()){
        String attrName = (String) en.nextElement();
        Object o = request.getSession().getAttribute(attrName);
            try {
                   session.lock(o, LockMode.NONE);
              } catch (HibernateException e) {
                    //just ignore this error, maybe this object 
                    //does not have a hibernate mapping
                }
            }
      filterChain.doFilter(request, response);
     }
    }
    In this case maybe you would like to refine what objects get re-attached to the Hibernate session.

    Cheers, Mircea

    Comment

    Working...
    X