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