7 Replies Latest reply on Aug 10, 2007 3:53 PM by dschaedl

    validation & selectManyListbox

    dschaedl

      JBoss 4.0.5
      JBoss Seam 1.2.1.GA

      My h:selectManyListbox displays my list correctly. But when I select entries and hit update to update my model containing this list I get a validation Error: "value is not valid" (on the webpage). How are the entries validated? why isn't it valid?
      If I switch off the validation and press the update-button nothing happens (Jboss is doing 'someting', but no logging, no page-forwarding; the update-action seems not to be called)
      The update works just fine if I deselect all entries in the listbox.

      The XHTML:

      ...
      <s:decorate id="coursesDecoration" template="layout/edit.xhtml">
       <ui:define name="label">alle PRC-Kurse</ui:define>
       <h:selectManyListbox value="#{trainer.courses}" >
       <s:selectItems value="#{courseLister.allCourses}" var="course" label="#{course.name}" />
       <s:convertEntity/>
       </h:selectManyListbox>
      </s:decorate>
      ...
      <h:commandButton id="updatetrainer" value="update" action="#{edittrainer.updateTrainer}" rendered="#{!edittrainer.newTrainer}" />
      


      Trainer
      @Entity
      @Name("trainer")
      public class Trainer extends Rower {
      
      private List<Course> courses;
      
      @ManyToMany
      public List<Course> getCourses() {
       return courses;
      }
      public void setCourses(List<Course> courses) {
       this.courses = courses;
      }
      ...
      


      Course
      @Entity
      @Name("course")
      public class Course implements Serializable{
      
      @ManyToMany(mappedBy="courses")
      private List<Trainer> trainers;
      ...
      


      CourseListerBean
      ...
      public List<Course> getAllCourses() {
       return em.createQuery("from Course c order by c.name desc").getResultList();
      }
      ...
      


      editTrainerBean
      @Stateful
      @Name("edittrainer")
      public class EditTrainerBean implements EditTrainer {
      
      @In(required=false)
      @Out
      private Trainer trainer;
      
      public void updateTrainer() {
       log.info("updating trainer: #{trainer.name} id:#{trainer.id}"); <-- never shown!
       em.persist(trainer);
      }
      ...
      


      any ideas?

      Daniel

        • 1. Re: validation & selectManyListbox
          pmuir
          • 2. Re: validation & selectManyListbox
            wiberto

            I had a similar issue but not with validating. My equals() method was wrong and always returning false. Blame it on autoboxing!!

            anyway, I fixed the equals() and now my checkbox list is selected appropriately based on the objects in the list. Which is a good sign.

            But still when I try to submit the form I get this message in the console (I don't see a stack trace or anything else)

            sourceId=j_id29:j_id60[severity=(ERROR 2), summary=(Error selecting object), detail=(Error selecting object)]
            


            Here's the tag:
            <h:selectManyCheckbox layout="pageDirection" value="#{user.userRoles}">
             <s:selectItems value="#{rolefinder.refreshedRoles}" var="currentRole" label="#{currentRole.roleName}"/>
             <s:convertEntity />
             </h:selectManyCheckbox>
            


            the userRoles is just a list of Role entities. Which has an @Id field:
            @Entity
            @Scope(SESSION)
            @Name("role")
            public class Role implements java.io.Serializable
            {
            
             private static final long serialVersionUID = 1L;
            
             // Fields
             @Id @GeneratedValue
             @Column(name="role_id")
             private int roleId;
            


            When the form is submitted I see that the equals method is called a bunch of times (once per item) but then the error message pops up.

            I'm running 1.2.1GA with AS 4.2.0GA

            Thanks!

            • 3. Re: validation & selectManyListbox
              pmuir

              I'm not sure where that error comes from. You'll need to use your debugger/the source to find what exception is being thrown (and caught, to give that error messages).

              • 4. Re: validation & selectManyListbox
                wiberto

                I was able to trace the calls until I found where the error was coming from. Basically it comes because the entityManager is null, and it tries to create one by name. Since I didn't have "entityManager" defined in my components.xml it never created one.

                Since you mentioned that Seam 2.0 had redone this area, I decided to upgrade before adding stuff to my components.xml since it seemed weird that it would have an entitymanager available for the rest of the stuff except for this (but I think I know why now)

                So I updated to Seam 2.0 and when I run it now I get this error:

                java.lang.NullPointerException
                 at org.jboss.seam.framework.EntityIdentifier.<init>(EntityIdentifier.java:15)
                 at org.jboss.seam.ui.converter.EntityConverterStore.put(EntityConverterStore.java:60)
                 at org.jboss.seam.ui.converter.EntityConverter.getAsString(EntityConverter.java:69)
                 at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getFormattedValue(HtmlBasicRenderer.java:469)
                 at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.renderOption(SelectManyCheckboxListRenderer.java:249)
                 at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:146)
                 at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:833)
                 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:896)
                 at javax.faces.render.Renderer.encodeChildren(Renderer.java:137)
                 at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:809)
                


                which leads me to believe it's the same issue. There is no entityManager. I didn't debug, but since it wasn't working before I wasn't expecting it to now.

                So I added the following to the components.xml:

                <persistence:managed-persistence-context name="entityManager"
                 auto-create="true"
                 persistence-unit-jndi-name="java:/numinsPersistenceUnit" />
                


                Now I get:
                org.hibernate.TransientObjectException: The instance was not associated with this session
                 at org.hibernate.impl.SessionImpl.getIdentifier(SessionImpl.java:1375)
                 at org.hibernate.search.impl.FullTextSessionImpl.getIdentifier(FullTextSessionImpl.java:331)
                 at org.jboss.seam.persistence.HibernateSessionProxy.getIdentifier(HibernateSessionProxy.java:205)
                 at org.jboss.seam.persistence.HibernatePersistenceProvider.getId(HibernatePersistenceProvider.java:114)
                 at org.jboss.seam.framework.EntityIdentifier.<init>(EntityIdentifier.java:15)
                 at org.jboss.seam.ui.converter.EntityConverterStore.put(EntityConverterStore.java:60)
                


                With this I think that the original object was loaded with something else and that another entitymanager is trying to use it now. Is this because of the whole Seam managed thing?

                I don't have my entities defined in components.xml. I just have the @Entity annotation in the class itself.

                I went ahed and changed the @Name to something else so it wouldn't collide and added it to the components.xml to try it out. So I added:

                <framework:entity-home name="role"
                 entity-class="com.numbersinsight.data.security.Role"
                 scope="session"
                 auto-create="true">
                 <framework:id>#{roleId}</framework:id>
                 </framework:entity-home>
                


                And the error message is:

                Caused by: java.lang.IllegalArgumentException: Can not set com.numbersinsight.data.security.Role field com.numbersinsight.admin.action.RoleFinderAction.role to org.jboss.seam.framework.EntityHome_$$_javassist_68
                 at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
                 at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
                 at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
                 at java.lang.reflect.Field.set(Field.java:657)
                 at org.jboss.seam.util.Reflections.set(Reflections.java:64)
                


                Why isn't it using the same entitymanager all around?
                I think I'm moving in the right direction and have an idea of how it's behaving, but it's confusing.

                I also tried using the hibernate-entity-home and got a class cast about going from a seam session to a hibernate session. I'll keep playing around to see what I can find.
                Any ideas?


                • 5. Re: validation & selectManyListbox
                  pmuir

                  I've fixed that error in CVS. The problem occurs because you aren't loading the entity using an SMPC (but probably @PersistenceContext). Make sure you read the item on the http://wiki.jboss.org/wiki/Wiki.jsp?page=SeamProblemsFAQ

                  • 6. Re: validation & selectManyListbox
                    wiberto

                    That did it. I was playing around with the entity itself and not with the entity manager. once I changed it to use @In instead of @PersistenceContext and I kept the manager defined in the components.xml it started working fine.

                    At least with all this playing around I learned a bit of the internals of Seam and you got to fix something in the code!!


                    Thanks for the help.

                    • 7. Re: validation & selectManyListbox
                      dschaedl

                      thank you for the solution to my original problem
                      It was indeed the missing 'equals'. Now it works :-)

                      Daniel