0 Replies Latest reply on Jun 4, 2008 3:52 PM by Antoine Sabot-Durand

    Lazy initialization Exception when lazy loading from rendered attribute

    Antoine Sabot-Durand Newbie

      Hello,


      I've got a strange pb on Seam 2.02SP1.


      I've got a first component browseHdl which initialize a list of item as a datamodel (items) from url parameters.



      @Stateful
      @Name("browseHdl")
      public class BrowseHandlerBean implements BrowseHandler {
      
           @In
           private EntityManager entityManager;
      
           @In(create = true)
           private SessionHandler sessionHdl;
      
           @In(create = true)
           OrderHome orderHome;
      
           @In
           ApplicationConfig applicationConfig;
      
           @Logger
           private Log log;
      
           @DataModel
           private List<Item> items;
      
           @DataModelSelection
           private Item item;
      
           @Factory("items")
           @SuppressWarnings("unchecked")
           public void findItems() {
                log.debug("Launching Request !");
                log.debug("group : {0} family : {1}", sessionHdl.getSelGroup(),
                          sessionHdl.getSelFamily());
                items = entityManager.createNamedQuery("browseProducts").setParameter(
                          "collectionRef", applicationConfig.getCollection())
                          .setParameter("groupRef", sessionHdl.getSelGroup())
                          .setParameter("familyRef", sessionHdl.getSelFamily())
                          .getResultList();
                log.debug("Request returned {0} items", items.size());
           }
      
           
      }




      This List is used in facelets page to list the items in a rich faces datagrid.


      To display information on each item in this page, I use another component (itemHdl) to be able to retrieve specific item content depending on user context (different languages and currencies). Also some items can contain more than one article in a list and some only one. That's why I made the isSingle() method. Of course the articles list is configured to be lazily loaded.


      @Stateful
      @Name("itemHdl")
      @AutoCreate
      public class ItemHandlerBean implements ItemHandler {
      
           @In(required = false)
           @Out(required = false)
           private Item item;
      
           private Article selArt;
      
           @Logger
           private Log log;
      
           @In
           private OrderHome orderHome;
      
           @In
           private SessionHandler sessionHdl;
      
           @In
           private FacesMessages facesMessages;
      
           @In
           private EntityManager entityManager;
      
           (...)
      
              // This method triggers the loading of articles list
           public boolean isSingle() {
                return item.getArticles().size() == 1;
           }
      
           (...)
      



      Here is the part of my page with the datagrid


      <rich:dataGrid id="browseAllSize" columns="3" elements="6"
           value="#{items}" var="item" styleClass="productList">
      
                <h:commandLink action="#{browseHdl.itemSelected}">
                <h:graphicImage
                     value="/data/products/#{item.style.collection.ref}/thumb/#{itemHdl.ref}.jpg"
                     styleClass="thumb"
                />
           </h:commandLink>
           <div><h:commandButton
                image="/layout/img/#{messages['plist.button.add2bag1']}"
                action="#{itemHdl.addToBag}" styleClass="button" rendered="#{itemHdl.single}">
                   </h:commandButton></div>
      (...)
      </rich:dataGrid>
      


      This give a Lazy initialization exception (transaction is not active) when fetching the isSingle value in the rendered attribute of the commandButton.
      If I change the code to this


      <rich:dataGrid id="browseAllSize" columns="3" elements="6"
           value="#{items}" var="item" styleClass="productList">
      
      #{itemHdl.single?'single':'multiple'} <!-- new line added -->
      
                <h:commandLink action="#{browseHdl.itemSelected}">
                <h:graphicImage
                     value="/data/products/#{item.style.collection.ref}/thumb/#{itemHdl.ref}.jpg"
                     styleClass="thumb"
                />
           </h:commandLink>
           <div><h:commandButton
                image="/layout/img/#{messages['plist.button.add2bag1']}"
                action="#{itemHdl.addToBag}" styleClass="button"> <!-- No more rendered attribute -->
                   </h:commandButton></div>
      (...)
      </rich:dataGrid>


      everything is fine. I keep fetching isSingle in an el test but no more in a rendered attribute.


      I'm not a specialist in JSF life cycle but I guess that rendered value are not evaluated in the same phase than pure el content. Could someone explain why this doesn't work and how to use a method trigering lazy loading in a rendered attribute or what I did wrong ?


      Thank you very much.


      Antoine