7 Replies Latest reply on Aug 10, 2007 3:53 PM by Daniel Schädler

    validation & selectManyListbox

    Daniel Schädler Newbie

      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

        • 2. Re: validation & selectManyListbox
          Jose Rubio Newbie

          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
            Pete Muir Master

            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
              Jose Rubio Newbie

              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
                Pete Muir Master

                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
                  Jose Rubio Newbie

                  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
                    Daniel Schädler Newbie

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

                    Daniel