Fetching Data Lazily On A New Page
darthmaul Mar 4, 2008 9:17 PMI am using JPA/Hibernate and Hibernate Search within my Seam application. I have a Widget entity that lazily loads its pricing history. The use case is pretty typical:
- Search for widgets on a form with a set of criteria.
- Display all widget search results in a table below the search form. The results include all the items found in the Widget table itself including the widget number, which is a link to another page.
- When you click on the widget number, you come to a
widget details
page that fetches all the 1:M relationships widgets have with other entities to get information like pricing history.
Note: Because I am using the RichFaces dataScroller with server-side paging, I have to use my own fancy data model and cannot use the standard Seam annotations like @DataModel and @DataModelSection.
The way I am doing my own version of @DataModelSection is to do the following:
<h:commandLink value="#{widget.number}" action="#{searchAction.setSelectedWidget(widget)}" />
where widget is the iteration variable.
Then through pages.xml, I navigate to the widget details page. All of that works fine until I get this:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.myapp.persistence.Widget.pricingHistory, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97) at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225) at javax.faces.model.ListDataModel.isRowAvailable(ListDataModel.java:99) at javax.faces.model.ListDataModel.setRowIndex(ListDataModel.java:174) at javax.faces.model.ListDataModel.setWrappedData(ListDataModel.java:209) at javax.faces.model.ListDataModel.<init>(ListDataModel.java:68) at org.ajax4jsf.component.SequenceDataAdaptor.getDataModel(SequenceDataAdaptor.java:79) at org.ajax4jsf.component.SequenceDataAdaptor.createDataModel(SequenceDataAdaptor.java:64) at org.ajax4jsf.component.UIDataAdaptor.getExtendedDataModel(UIDataAdaptor.java:592) at org.ajax4jsf.component.UIDataAdaptor.getRowIndex(UIDataAdaptor.java:299) at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source) at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source) at com.sun.facelets.util.DevTools.writeAttributes(DevTools.java:240) at com.sun.facelets.util.DevTools.writeStart(DevTools.java:284) at com.sun.facelets.util.DevTools.writeComponent(DevTools.java:189) at com.sun.facelets.util.DevTools.writeComponent(DevTools.java:207) at com.sun.facelets.util.DevTools.writeComponent(DevTools.java:207) at com.sun.facelets.util.DevTools.writeComponent(DevTools.java:207) at com.sun.facelets.util.DevTools.writeComponent(DevTools.java:207) at com.sun.facelets.util.DevTools.debugHtml(DevTools.java:133)
Now I understand that the Widget has been detatched from the JPA EntityManager by this time. But when I click that link and come to the details page, I would like the entity to be smart enough to open another session behind the scenes and grab the information it now needs.
Is such a thing possible? How do I accomplish what I am trying to do?
Any insight is appreciated.
Thanks.