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.  [ 12 posts ] 
Author Message
 Post subject: Stupid (?) transaction/session issue...
PostPosted: Thu Aug 24, 2006 9:58 am 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
Hibernate version: 3.1(.?), newbie to v3.
App server: Weblogic 8.1, newbie to Weblogic.
Deadline: Looming and starting to make that swooshy sound.
Hibernate config file: Appended at end of message.

Recipe for disaster, and my sanity-checking code is kicking my butt.

I'm having issues grokking session/transaction "stuff," specifically relating to the retrieval of child sets mapped to a previously-retrieved object, especially in forwarded-to JSPs. Actual questions generally in bold.

In a load-on-startup servlet I bind a session factory to JNDI (is this wrong?):

Code:
                sessions = new Configuration().configure().buildSessionFactory();
                getServletContext().setAttribute("session-factory", sessions);


I retrieve a list of objects in a servlet originally like this:

Code:
        SessionFactory sf = (SessionFactory) getServletContext().getAttribute("session-factory");
        sf.getCurrentSession().beginTransaction();
        List apps = appDao.findByExample(new LhpApp());
        request_.setAttribute("apps", appDao.findByExample(new LhpApp()));
        sf.getCurrentSession().getTransaction().commit();
        // fwd to JSP


In the JSP when I attempted to iterate over a set contained in those objects (i.e., each object I'm c:forEach-ing over has a list of contained objects I also want to c:forEach over), I get an exception saying hey, you have to be in a transaction:

Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.foo.bar.model.App.Users, no session or session was closed


Irritating, and I'm already assuming I am doing something incorrectly. (Am I?)

So after thrashing around awhile I said okay, I'll wrap all my requests in a filter that make a transaction, and take out the session/transaction code in the chunk above. (Is this a Really Bad Idea?)

Code:
    public void doFilter(ServletRequest arg0_, ServletResponse arg1_, FilterChain arg2_) throws IOException, ServletException {
        SessionFactory sf = (SessionFactory) filterConfig.getServletContext().getAttribute("session-factory");
        Transaction tx = sf.getCurrentSession().beginTransaction();
       
        arg2_.doFilter(arg0_, arg1_);

        sf.getCurrentSession().flush();
        tx.commit();


Thing of beauty-ish. Retrieves the "parent" object, iterates over the sub-elements I need. Filter gets hit twice, once for the servlet, once for the JSP. Two transactions; I can live with that (am I supposed to be living with that, though?!)

Of course, the same request runs through the filter twice, because I'm forwarding to a JSP. So I get an error on the flush. I take out the flush; the commit flails because the second time through I'm still operating on the same Transaction.

Code:
org.hibernate.TransactionException: Transaction not successfully started


There's this whole JTA thing that I know nothing about; would that solve this problem? I've already spent nearly a week on Hibernate3, first using the MyEclipse Hibernate tools, but we can't introduce that dependency so I switched to Middlegen, but was then told to use the Hibernate tools, which generate a DAO that looks like this (trimmed for brevity):

Code:
    private final SessionFactory sessionFactory = getSessionFactory();
   
    protected SessionFactory getSessionFactory() {
        return (SessionFactory) new InitialContext().lookup("SessionFactory");
    }

    //...

   public List findByExample(LhpApp instance) {
            List results = sessionFactory.getCurrentSession()
                    .createCriteria("com.thg.husky.model.LhpApp")
                    .add(Example.create(instance))
            .list();
            return results;
    }


I am going to look at the ironically-named CaveatEmptor app because I am quite convinced I am doing something phenomonomonomally ridiculous, because I never had any of these issues with my two v2 projects, but I was less involved in the genesis, and am just ignorant.

Answers greatly appreciated, hints and pointers gladly accepted, but I've already looked in the reference, FAQs, Google, etc. and so far nothing has been "helpful enough," so I am full of sorrow. Apologies for the lengthy clueless n00b post.

Thanks much,
Dave


Top
 Profile  
 
 Post subject: Quick followup
PostPosted: Thu Aug 24, 2006 10:19 am 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
I replaced my Filter and startup servlet with the HibernateThreadFilter/HibernateUtil from CaveatEmptor. Same issue with the
Code:
org.hibernate.TransactionException: Transaction not successfully started


The HibernateExtendedThreadFilter is what I was going to implement (so it knows when I'm really done with the "conversation") but this won't help me in a JSP.

Now, the actual application is going to be in Struts/Tiles and I am going to write a test Action that attempts to do the same thing. Maybe the Struts/Tiles processing model won't share this same issue (haven't worked in Struts for a year) but I kinda think it does.

So is there something obvious I'm missing, is this use-case simply not supported (unthinkable), or what?

Thanks again,
Dave


Top
 Profile  
 
 Post subject: Yet another followup, partial solution, still have ?s.
PostPosted: Thu Aug 24, 2006 11:48 am 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
As expected, switching to JTA transactions (which I believe I did correctly) doesn't solve the problem since the filter is being hit a second time for the included JSP (also under Struts/Tiles).

Originally my filter was mapped to "/*"... I changed this to "*.do" (just the Struts Actions) to avoid having the filter run on an included/forwarded-to JSP.

This side-stepped the problem and the code now works.

Not that I'm not all happy and perky, but it was my impression that under Servlet 2.3 that filters were only run on the initial user request, not forwards or includes... is this not true under Weblogic 8.1?

Also, how do real programmers deal with this (I'm sure completely common and solved) issue??? I remember seeing something in the docs about handling exceptions and will look, but just in case someone is actually reading this, if the exceptions are being caught and tx's rolled back in the filter, how do people normally handle having to go somewhere based on an exceptional condition?

*sigh*

The amount of things I need to know as a JEE developer are rapidly approaching a critical mass; I am beginning to lose IQ points.

Thanks,
Dave


Top
 Profile  
 
 Post subject: Mappingfile required
PostPosted: Thu Aug 24, 2006 11:51 am 
Beginner
Beginner

Joined: Tue Aug 08, 2006 11:53 am
Posts: 37
Without your mapping file it is difficult to answer your question.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 11:54 am 
Beginner
Beginner

Joined: Tue Aug 08, 2006 11:53 am
Posts: 37
My suggestion is to always demarcate transaction in the business layer (facade etc). and use session-per-request with detached objects.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:00 pm 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
triveni wrote:
My suggestion is to always demarcate transaction in the business layer (facade etc). and use session-per-request with detached objects.


On a practical level, this means what?

If I'm retrieving a list of objects in an action then want to iterate over a one-to-many set contained in one of those objects in an included/forward JSP (Struts/Tiles) I'm not even sure how I'd go about that, especially considering we're trying to use the HibernateTools hbm2java/hbm2dao tasks w/o modifying templates.

Also, does this mean that the filter idea as implemented in CaveatEmptor isn't a best practice?

Thanks,
Dave


Top
 Profile  
 
 Post subject: Struts Action -> Business/Service Layer -> DAO -> O
PostPosted: Thu Aug 24, 2006 12:13 pm 
Beginner
Beginner

Joined: Tue Aug 08, 2006 11:53 am
Posts: 37
To my knowledge, doing an eager fetch while limiting the result set to a considerable size is the best solution. In this way you no need to care about implementing custome filters. I always try to demarcate transactions in the business layer, the layer where they are applicable the most!

In your case, checkout the open-seesion-in-view pattern or session.disconnect etc.

Pls try to rate if this helped!


Top
 Profile  
 
 Post subject: Re: Struts Action -> Business/Service Layer -> DAO -&a
PostPosted: Thu Aug 24, 2006 12:22 pm 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
triveni wrote:
To my knowledge, doing an eager fetch while limiting the result set to a considerable size is the best solution. In this way you no need to care about implementing custome filters. I always try to demarcate transactions in the business layer, the layer where they are applicable the most!

In your case, checkout the open-seesion-in-view pattern or session.disconnect etc.


... so this would mean that I would need to fetch everything in my Action that I wanted to display in the JSP?! To me, that (at least partially) defeats the purpose of having an ORM layer.

My goal in having an ORM layer is to distance myself from the underlying persistence of objects. If I am forced to know that I have to pre-fetch everything I need on the presentation side I've lost one of the greatest advantages that Hibernate gave me, and I now have to consider everything the presentation side needs, and if the presentation side needs something I didn't explicitly fetch then I have to go in and change my code. With the filter I don't.

It may be that I'm completely misunderstanding what you're saying, though. I hope I am! :)

Dave


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:33 pm 
Beginner
Beginner

Joined: Tue Aug 08, 2006 11:53 am
Posts: 37
Result set size, fetch strategy, session strategy, transaction handling strategy (JTA or JDBC) etc are architecutre level decisions that need to be made and these decisions drive the way you code!

Hibernate can only do so much as a persistence service (OR Mapping), the discussion we are having here is however the responsibility of the application infrastructure, or framework.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:40 pm 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
triveni wrote:
Result set size, fetch strategy, session strategy, transaction handling strategy (JTA or JDBC) etc are architecutre level decisions that need to be made and these decisions drive the way you code!

Hibernate can only do so much as a persistence service (OR Mapping), the discussion we are having here is however the responsibility of the application infrastructure, or framework.


Does this mean you have no input regarding my question(s)? Right now all I care about knowing is how the session/transaction issue is generally solved.

Right now I'm "solving" it the way CaveatEmptor solves it and have tweaked my filter mapping to ensure it's only run once per request (so far I do not include any Actions; this may bite us later, hard to say). The filter strategy is also one mentioned in most documentation.

Managing the transactions in my business layer (or facade of, etc.) is how I've done things in the past, but with my previous DAOs I was able to access lazily-populated lists inside an included JSP; the DAOs generated with the latest HibernateTools appear not to allow that. It may be a 2 vs. 3 issue as well; a lot of things are different in my current environment.

Thanks again,
Dave


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 12:51 pm 
Beginner
Beginner

Joined: Tue Aug 08, 2006 11:53 am
Posts: 37
As I have indicated in my earlier posts you can look into the following options

open-seesion-in-view pattern or session.disconnect etc. http://hibernate.org/43.html#A8
http://www-03.ibm.com/developerworks/bl ... lationship


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 24, 2006 1:03 pm 
Newbie

Joined: Thu Aug 24, 2006 8:27 am
Posts: 10
triveni wrote:
As I have indicated in my earlier posts you can look into the following options

open-seesion-in-view pattern or session.disconnect etc. http://hibernate.org/43.html#A8
http://www-03.ibm.com/developerworks/bl ... lationship


Yeah, the first Hibernate docs link are what pointed me in the filter direction, as that seems to fit with the way I want to be able to code.

I'll spend a small amount of time looking in to some of the other solutions presented, and for some queries I will probably want to implement the initial fetch in the action (like for a known-large result set) otherwise... I think I'll leave things as they stand (for now :)

Thanks,
Dave


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