13 Replies Latest reply on Jun 29, 2006 11:54 PM by Gavin King

    Stateless Login Problems

    flo thomas Newbie

      Hi,
      I have a question regarding the sample LoginAction I find in the examples. They are always Stateless, why is this the case? I have problems with lazy loading, because I need to access a collection from the User that logs in at a later point in time and thus I always get a lazy loading exception.

      I tried using the @In(create=true) for the EntityManager but then I get problems when deploying "In attribute requires value for component login.em".

      Any clues?

      Thanks!

        • 1. Re: Stateless Login Problems
          Pete Muir Master

          I think you are on the right track by switching to a Seam managed persistence context. Have you configured a SMPC in components.xml called em as described in the docs[1]?

          [1]http://docs.jboss.com/seam/1.0.1.GA/reference/en/html/configuration.html#d0e4853

          • 2. Re: Stateless Login Problems
            flo thomas Newbie

            Hi,
            thanks for the link.
            I configured it just as the tutorial proposes. However, I am still getting those LIE exceptions, even though I initialize all of my EntityManagers via @In(create=true)

            Any clues to that?

            Thanks

            • 3. Re: Stateless Login Problems
              Pete Muir Master

              I suggest you post a (simple as possible) example of the JSF pages, classes and stacktrace where you get the LIE

              • 4. Re: Stateless Login Problems
                flo thomas Newbie

                Hi,
                thanks for the answer:
                The BackingBean

                @Stateful
                @Scope(CONVERSATION)
                @Name("relationshipManager")
                @LoggedIn
                public class RelationshipManagerAction implements RelationshipManager {
                
                 @In(create=true)
                 private EntityManager em;
                
                 @DataModel
                 List<Relationship> relationships;
                
                 @DataModelSelection
                 Relationship relationship;
                
                 @In(create=true)
                 private transient FacesMessages facesMessages;
                
                
                 @In @Out(required=false)
                 //The currently logged in user
                 private Person person;
                
                 @In
                 private Group group;
                
                 @SuppressWarnings("unchecked")
                 @Factory
                 public void find() {
                 relationships = new LinkedList();
                 relationships.addAll(em.createQuery("from Group where owner = :user")
                 .setParameter("user",person)
                 .getResultList());
                 relationships.addAll(em.createQuery("select from BinaryRelationship where from = :user")
                 .setParameter("user",person)
                 .getResultList());
                 }
                
                 public void addGroup() {
                 group.setOwner(person);
                 person.getRelationships().add(group);
                 relationships.add(group);
                 facesMessages.add("Successfully registered as #{newGroup.name}");
                 }

                the view:

                <h:form>
                 <fieldset>
                 <s:validateAll>
                 <h1>Group</h1>
                 <div class="entry">
                 <div class="label"><h:outputLabel for="groupName">Name:</h:outputLabel></div>
                 <div class="input">
                 <h:inputText id="groupName" value="#{group.name}" required="true"/>
                 <br/><span class="errors"><h:message for="groupName" /></span>
                 </div>
                 </div>
                 </s:validateAll>
                 <div class="entry errors"><h:messages globalOnly="true"/></div>
                 <div class="entry">
                 <div class="label"><f:verbatim>&#160;</f:verbatim></div>
                 <div class="input">
                 <h:commandButton value="Save" action="#{relationshipManager.addGroup}" class="button"/>&#160;
                 </div>
                 </div>
                 </fieldset>
                 </h:form>


                • 5. Re: Stateless Login Problems
                  flo thomas Newbie

                  I forgot the stack:

                  
                  org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: de.myties.core.nodes.Person.relationships, 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.initialize(AbstractPersistentCollection.java:343)
                   at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:183)
                   at org.hibernate.collection.PersistentSet.add(PersistentSet.java:165)
                   at de.myties.core.portal.register.RelationshipManagerAction.addGroup(RelationshipManagerAction.java:82)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
                   at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
                   at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                   at org.jboss.seam.interceptors.ValidationInterceptor.validateTargetComponent(ValidationInterceptor.java:64)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                   at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:90)
                   at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
                   at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:33)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                   at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:90)
                   at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
                   at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:21)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                   at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:90)
                   at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:60)
                   at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:82)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                  ...
                  


                  • 6. Re: Stateless Login Problems
                    flo thomas Newbie

                    To further explain what i want to do:
                    I have the LoginAction (taken from the booking example) which is stateless, but I need to access at a later point in time, some collections (the Relationships) of the user that had logged in through the LoginAction, so I figured this would work if I use the"@In EntityManager em"...

                    However I still get the lazy initialization exceptions, I think the problem is probably in the LoginAction, but I don't think that it should be stateful...

                    Thanks!

                    • 7. Re: Stateless Login Problems
                      flo thomas Newbie

                      Mhm,
                      I modified the LoginAction to be of Scope "CONVERSATION", that got rid of the LIE. Is there anything wrong with this approach?
                      Thanks

                      • 8. Re: Stateless Login Problems
                        flo thomas Newbie

                        mhm... it seems like there is still something wrong... getting the LIE again...

                        • 9. Re: Stateless Login Problems
                          Gavin King Master

                          The examples always use stateless, because login is by nature a stateless process.

                          Now, it sounds like your problem is that you store the user in session scope, and then later try to access its collection. This is not going to work. Seam-managed PCs solve LIE problems for _conversational_ data, not for session-scoped data.

                          If I were you I would fetch the collection eagerly, during login.

                          • 10. Re: Stateless Login Problems
                            flo thomas Newbie

                            Thanks Gavin,
                            I changed the scope to @Scope(CONVERSATION) for now on the login and ensured that the Person has a @In & @Out tag.

                            This got rid of LIE, is that a bad approach? If so, can you point me to the doc for eager fetching?

                            Thanks!!!

                            • 11. Re: Stateless Login Problems
                              Norman Richards Master

                              If you store your user with the conversation, the login information will disappear when you end the conversation. This would almost never be the behavior you want.

                              To eagerly load a relationship, use a join fetch. Check out any EJB3 book (like Bill's new one with O'Reilly) to see how to do that. Here are a couple of examples from the Seam examples:

                              em.createQuery("from Order o join fetch o.orderLines where o.orderId = :orderId")
                              
                              entityManager.createQuery("from Blog b left join fetch b.blogEntries")
                              




                              • 12. Re: Stateless Login Problems
                                flo thomas Newbie

                                Thanks for the input.
                                The problem is that the amount of data to be loaded might be large, so I would have to keep that in memory the whole time. Could I not just leave the conversation open until the user logs out just like the SessionConversationPattern often used in Hibernate? That would allow me to keep the Person within one "Session"-Context, so that I can access any elements at any point in time without LIE...

                                Thanks

                                • 13. Re: Stateless Login Problems
                                  Gavin King Master

                                  It would be better to re-load the user inside the scope of the conversation. ie:

                                  User user = em.find(User.class, sessionUser.getId())