14 Replies Latest reply on Jan 2, 2007 3:27 PM by modoc

    Seam, EJB3, POJOs, nested one to many relationships

    modoc

      I'm working with Seam 1.1, and building a new application. This application has an Account object which is an Entity POJO. The account has many Sites, a Site has many Flows, and a Flow has many Actions. All Entity POJOs. All One to Many relationships are defined using Lists, as that is what makes sense.

      Upon login, a User object gets loaded, there is a Many to One relationship between Users and Accounts.

      This is the getFlows method on the Site object, as an example, all the relationships are similar:

      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "site")
       @OrderBy("id")
       public List<Flow> getFlows() {
       return this.mFlows;
       }



      My Login action uses an EntityManager provided by Seam:

      @In(create = true)
       private EntityManager entityManager;


      and in my persistance.xml I have:

      <property name="jboss.entity.manager.factory.jndi.name" value="java:/keynoteEntityManagerFactory" />


      and in my components.xml I have:

      <component name="entityManager"
       class="org.jboss.seam.core.ManagedPersistenceContext">
       <property name="persistenceUnitJndiName">
       java:/keynoteEntityManagerFactory
       </property>
       </component>


      My problems are this:

      If I try to use lazy loading, I can get the account from the user, and I can get the Sites from the Account, but when I try to get the Flows from the Site I get these errors:
      01:41:55,247 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: com.digitalsanctuary.keynote.ejb.Site.flows, no session or session was closed
      org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.digitalsanctuary.keynote.ejb.Site.flows, no session or session was closed


      If I try to use Eager loading I get:

      cannot simultaneously fetch multiple bags


      Errors. If I try to use the @IndexColumn annotation as per the threads on this error in Hibernate forums, then I get empty items in my list until the actual index id shows up (i.e. The list of Sites for a given account may have primary key id's of 5, 6, 7, and 8. When I use the IndexColumn annotation, my List of Sites ends up with 5 empty items before the 4 real items (this not only causes code issues, but makes my data tables look awful).


      Basically I can't figure out the right combination of settings to get things to work. Ideally I'd like to Lazily load everything, as many user flows won't require the sub-items, however, I can't figure out how to avoid the LIE, even though I'm using the Seam EntityManager.

      I'm new to EJB3, and pretty new to Seam, but I've been pouring over the docs and forums and so far haven't worked it out. Any help would be greatly appreciated. Thanks!

      Modoc


        • 1. Re: Seam, EJB3, POJOs, nested one to many relationships
          modoc

          More info on the LIE:

          It happens as I have multiple pages to drill through the hierarchy. I.e., you login, pick the site you want to deal with, pick the flow you want to work with, etc... Is it because my entityManager is only conversation scoped, and after I get past the login->Sites page the conversation is over? If so, how do I make this work?

          I don't want to put the whole user session into a long conversation, and yet the user might go back up to the sites list, and pick another flow, and then deal with actions in that new flows, etc...

          What am I missing here?

          Modoc




          actual code throwing the LIE:

          <h:outputText rendered="#{session.siteInContext != null and session.siteInContext.flows !=null and session.siteInContext.flowsCount>0}">
          



           @Transient
           public int getFlowsCount() {
           if (this.mFlows == null) {
           return 0;
           }
           return this.getFlows().size();
           }
          
           /**
           * @return the flows
           */
           @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "site")
           @OrderBy("id")
           public List<Flow> getFlows() {
           return this.mFlows;
           }


          • 2. Re: Seam, EJB3, POJOs, nested one to many relationships

             

            It happens as I have multiple pages to drill through the hierarchy. I.e., you login, pick the site you want to deal with, pick the flow you want to work with, etc...


            That maybe the problem.

            If you want to avoid LIE and support this kind of use-case, you need a long running conversation. Seam provides a managed persistence context for you that will also be long-running.

            Otherwise, you may have to do a em.merge() of the detached object in question to bring it back as managed to avoid LIE.

            Hope this helps.

            • 3. Re: Seam, EJB3, POJOs, nested one to many relationships
              modoc

              Yeah, I only thought of that after I made the initial post, it makes sense based on the behavior I'm seeing. It just doesn't seem right that I should have to define the entire user experience as a single conversation. I mean what if I need to have multiple conversations to allow multiple browsers/tabs?

              I may be spoiled by ATG Repositories, but why can't the persistence code simply fetch the data I need? It knows what object I'm working with and which object(s) I need. I guess I don't know enough about EJB3 sessions or something. I guess that's something I need to research more of and/or take up on the EJB3 forum.

              Anyhow, I can't be the only person with a hierarchy of data driving the majority of the user experience like this. Is the only answer to use a single user-session encompassing long running conversation? That or EAGER load everything into memory at the beginning (which still leaves me with my bag/indexcolumn issues)? Obviously I could also replace my nice simple EJB POJOs with "smarter" object that use the entityManager to populate themselves manually as needed, but that seems to be throwing away most of the POJO/annotation/EJB3 goodness.

              How have other people solved this type of issue?

              Regards,

              Modoc

              • 4. Re: Seam, EJB3, POJOs, nested one to many relationships

                I don't understand why you are trying to avoid using conversations for this kind of use-case. I think this is precisely the kind of problems conversations are trying to solve. You have a stateful hierarchy in which you need manage for a variable amount of time.

                Unless I am understanding the requirements.

                • 5. Re: Seam, EJB3, POJOs, nested one to many relationships

                  Sorry, misunderstanding.

                  • 6. Re: Seam, EJB3, POJOs, nested one to many relationships
                    modoc

                    Basically it doesn't make sense to me to have a long running conversation that spans the entire user session every time. Maybe that is a common usage for lrcs, but it seems redundant to me.

                    Also, I may very well want conversational state for multiple browser windows within a user session. Can I have nested conversations?

                    At that point I guess I don't understand the difference between a session and a session-length long running conversation.

                    • 7. Re: Seam, EJB3, POJOs, nested one to many relationships
                      modoc

                      Upon reading more about conversations, and nested conversations, maybe this is the way to go. I'll poke at it. Thanks!

                      If anyone has other ideas, let me know.

                      Modoc

                      • 8. Re: Seam, EJB3, POJOs, nested one to many relationships

                         

                        Can I have nested conversations?

                        Yes


                        At that point I guess I don't understand the difference between a session and a session-length long running conversation.


                        I'm not sure what you mean by "session-length long running conversation." The scope of a long running conversation in Seam is generally longer than a page but shorter than a session. The exact length is determined by your demarcation using semantics such as @Begin and @End.

                        • 9. Re: Seam, EJB3, POJOs, nested one to many relationships
                          modoc

                          I guess what I meant was that for the application I'm building, the data would need to be available throughout the entire session lifespan, meaning my conversation would start at login, and end with session expiration/log-out.

                          If a conversation lasting that long will solve all the LIE issues, why not have a default conversation wrapping the entire session life to avoid any LIE issues at all? *shrug*

                          Anyhow, thanks for the info, I'm going to start playing with the nested conversation stuff and see if it gets things going for me.

                          Regards,

                          Modoc

                          • 10. Re: Seam, EJB3, POJOs, nested one to many relationships
                            modoc

                            By starting a conversation at login, and ending it when the session is destroyed it seems to let me do lazy loading without issue.

                            Thanks! Sorry I didn't get it before.

                            Modoc

                            • 11. Re: Seam, EJB3, POJOs, nested one to many relationships

                              Be aware that a long running conversation is a specified timeout period, default to 10 minutes if you don't specify it in your components.xml.

                              • 12. Re: Seam, EJB3, POJOs, nested one to many relationships
                                modoc

                                Oh thanks! Good point. Is that timeout from last activity in the conversation or from the Beginning?

                                • 13. Re: Seam, EJB3, POJOs, nested one to many relationships

                                   

                                  Is that timeout from last activity in the conversation or from the Beginning?


                                  Last request

                                  • 14. Re: Seam, EJB3, POJOs, nested one to many relationships
                                    modoc

                                    Oh ok. Thanks!