Hi,
I'm beating my head against the wall trying to resolve lazy exceptions. I have implemented the Open-session-in-view. I have done this in the TilesRequestProcessor that we extend from the regular Struts request processor. We do this, because tiles causes a regular filter to be called multiple times in one request. Using logger output I can see that the tilesrequestprocessor actually gets opened and closed once per request, as it should
The structure of the domain model basically is:
* categories
+ items
+relatedItems
+relatedGuides
+ guides
+ relatedGuides
etc
Hibernate version:2.1.8
Mapping documents: I've edited these slightly to remove simple properties and hopefully make it a little easier to read. <hibernate-mapping > <class name="nl.tfe.ddb.business.entities.Category" table="Categories" >
<id name="id" column="id" type="long" unsaved-value="null" > <generator class="native"> </generator> </id>
<set name="items" lazy="true" inverse="false" cascade="save-update" sort="unsorted" >
<key column="FK_category_id" > </key>
<one-to-many class="nl.tfe.ddb.business.entities.Item" />
</set>
<set name="guides" lazy="true" inverse="false" cascade="save-update" sort="unsorted" >
<key column="FK_category_id" > </key>
<one-to-many class="nl.tfe.ddb.business.entities.Guide" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping> <class name="nl.tfe.ddb.business.entities.IItem" table="Items" >
<id name="id" column="id" type="long" unsaved-value="0" > <generator class="native"> </generator> </id>
<discriminator column="Subclass" type="string" length="5" />
<subclass name="nl.tfe.ddb.business.entities.Item" discriminator-value="ITEM" >
<set name="relatedItems" table="Itemrelatedinfo" lazy="true" cascade="none" sort="unsorted" >
<key column="FK_item_id" > </key>
<many-to-many class="nl.tfe.ddb.business.entities.Item" column="FK_itemrelated_id" outer-join="auto" />
</set>
<set name="relatedGuides" table="Itemrelatedguideinfo" lazy="true" cascade="none" sort="unsorted" >
<key column="FK_item_id" > </key>
<many-to-many class="nl.tfe.ddb.business.entities.Guide" column="FK_relatedguide_id" outer-join="auto" />
</set>
<many-to-one name="category" class="nl.tfe.ddb.business.entities.Category" cascade="none" outer-join="auto" update="true" insert="true" column="FK_category_id" />
<set name="orderForms" table="Items_OrderForms" lazy="true" cascade="none" sort="unsorted" >
<key column="FK_item_id" > </key>
<many-to-many class="nl.tfe.ddb.business.entities.OrderForms" column="FK_orderform_id" outer-join="auto" />
</set>
<set name="itemVersions" table="item_versions" lazy="true" inverse="true" cascade="all-delete-orphan" sort="unsorted" >
<key column="FK_itemid" > </key>
<one-to-many class="nl.tfe.ddb.business.entities.ItemVersions" />
</set>
</subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close(): public class HibernateTilesProcessor extends TilesRequestProcessor {
public void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { synchronized (request.getSession()) { User user = null; user = (User) request.getSession().getAttribute("user"); if (user != null) { try { HibernateSession.currentSession().lock(user, LockMode.NONE); } catch (HibernateException he) { throw new ServletException(he); } catch (Exception e) { throw new ServletException(e); } } } try { super.process(request, response); } catch (Exception e) { logger.error(e); } finally { try { HibernateSession.closeSession(); } catch (Exception e) { throw new ServletException(e); } } }
Full stack trace of any exception that occurs: Hibernate: select count(*) as x0_0_ from Categories category0_ inner join Items items1_ on category0_.id=items1_.FK_category_id where (category0_.id=? )and((items1_.status=? )or(items1_.status=? )) DEBUG nl.tfe.ddb.data.hibernate.CategoryDAO : itemcount, category: Leefomgeving & Veiligheid = 15 ERROR net.sf.hibernate.LazyInitializationException : Failed to lazily initialize a collection - no session or session was closed net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:209) at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71) at net.sf.hibernate.collection.Set.iterator(Set.java:130) at nl.tfe.ddb.business.application.ProductHelper.getOrganizedirectly(ProductHelper.java:691) at nl.tfe.ddb.business.delegate.ProductDelegate.getCategoryPageContent(ProductDelegate.java:127) at nl.tfe.ddb.process.application.DisplayProductCategoryAction.execute(DisplayProductCategoryAction.java:114) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226) at nl.tfe.ddb.util.HibernateTilesProcessor.process(HibernateTilesProcessor.java:67) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:118) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929) at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705) at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683) at java.lang.Thread.run(Unknown Source)
Name and version of the database you are using:mySQL4.1
HibernateSession public static Session currentSession() throws DataBaseException { Session s = (Session) threadSession.get(); try { if(s != null && !s.isOpen()){ s = null; } if(s == null) { s = sessionFactory.openSession(); threadSession.set(s); } } catch (HibernateException he) { logger.error("Error in opening session", he); throw new DataBaseException(he); } return s; }
public static void closeSession()throws DataBaseException { try{ Session s = (Session) threadSession.get(); threadSession.set(null); if(s != null && s.isOpen())s.close(); }catch(HibernateException he){ throw new DataBaseException(he); } }
Any help's appreciated.
Kind regards,
Marc
|