6 Replies Latest reply on Jan 9, 2008 10:30 AM by fissy101

    Backing a selectOneMenu with a Collection

    fissy101

      Hello,

      I am trying to write a simple database application using seam. There are two entities, User and Movie. There is a ManyToOne relationship between them currently. From Movie.java:

       @ManyToOne
       public User getOwner() {return owner;}
       public void setOwner(User owner) {this.owner = owner;}
      

      There is a movie.xhtml view which is used to create and edit Movie entities before persisting them. One of the required fields in this form is the owner of the Movie:
      <h:selectOneMenu value="#{movie.owner}" required="true">
       <s:selectItems value="#{allusers}" var="user" label="#{user.firstName} #{user.familyName}" noSelectionLabel="Please Select..." cache="false"/>
      </h:selectOneMenu>
      

      The allusers Collection referred to here is a factory method defined in a UserList.java 'action' class:
       @Factory("allusers")
       public void findAllUsers() {
       System.out.println("findAllUsers called");
       allusers = em.createQuery("select u from User u").getResultList();
       }
      


      When movie.xhtml is viewed, the selectOneMenu is populated with the firstName familyName, which is great. Unfortunately, when the form is submitted to create and persist the new Movie object, the following error is shown either in a big stack trace or just the facesMessages if I enable that in the page:
       * /admin/movie.xhtml @31,57 value="#{movie.owner}": java.lang.IllegalArgumentException: argument type mismatch
      

      I don't really know where to start with this, as I don't know what is expecting an argument, or what what type it is expecting, or what I am sending it. Can anyone help?

      Many thanks,
      Dave

        • 1. Re: Backing a selectOneMenu with a Collection

          I think the factory should return an array of User Objects

          • 2. Re: Backing a selectOneMenu with a Collection
            pmuir

            Don't you need s:convertEntity?

            • 3. Re: Backing a selectOneMenu with a Collection
              sannegrinovero

              wat's the declared type of "allusers"?
              Using "Collection" will get you problems, use a List.
              Also check you Outject the variable.

              • 4. Re: Backing a selectOneMenu with a Collection

                take a look at following seam-example:

                jboss-seam-2.0.0.CR2\examples\ui\view\selectItems.xhtml

                I think the "Continent of Birth" is close, to what U want

                this might also help U:
                http://shrubbery.mynetgear.net/wiki/Seam#I.27ve_made_an_.40Factory.28.22foo.22.29_method.2C_but_.22foo.22_is_always_null.21

                • 5. Re: Backing a selectOneMenu with a Collection
                  fissy101

                  mars1412,
                  Yes it does, but is that the part which is complaining about the mismatched types, because that method isn't called when the form is submitted.

                  sannegrinovero,
                  The factory creates this list:

                   @DataModel
                   private List<User> allusers;
                  

                  It is a list, i meant Collection in a generic sense, sorry for not being more exact. The @DataModel annotation is for use in another view.

                  Pete,
                  I have tried adding <s:convertEntity/> to the selectOneMenu, but without success. Following the documentation at http://docs.jboss.com/seam/2.0.0.GA/reference/en/html/controls.html, I have added
                   <persistence:managed-persistence-context name="entityManager"
                   auto-create="true"
                   persistence-unit-jndi-name="java:/EntityManagerFactories/entityManager"/>
                  

                  to my components.xml, and have edited my persistence.xml to look like:
                  <persistence>
                   <persistence-unit name="MovieDataSource">
                   <provider>
                   org.hibernate.ejb.HibernatePersistence
                   </provider>
                   <jta-data-source>
                   java:/MovieDataSource
                   </jta-data-source>
                   <properties>
                   <property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactories/entityManager"/>
                   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
                   <property name="hibernate.hbm2ddl.auto" value="create-drop" />
                   </properties>
                   </persistence-unit>
                  </persistence>
                  

                  I *think* the next step is to change all my @PersistenceContext(type=EXTENDED) private EntityManager em; into @In EntityManager entityManager; and it might magically work. Unfortunately the application no longer deploys with this error:
                  Caused by: org.dom4j.DocumentException: Error on line 17 of document : The prefix "persistence" for element "persistence:managed-persistence-context" is not bound. Nested exception: The prefix "persistence" for element "persistence:managed-persistence-context" is not bound.
                   at org.dom4j.io.SAXReader.read(SAXReader.java:482)
                   at org.dom4j.io.SAXReader.read(SAXReader.java:343)
                   at org.jboss.seam.util.XML.getRootElement(XML.java:21)
                   at org.jboss.seam.init.Initialization.initComponentsFromXmlDocument(Initialization.java:132)
                   ... 92 more
                  

                  Do you know how I can fix this, and if so, am I on the right track?

                  Dave

                  • 6. Re: Backing a selectOneMenu with a Collection
                    fissy101

                    Thanks Mars1412, the continent example did help. I was missing the schema definition for persistence, very obvious now that I look at my last error message again.

                    For anyone who is having a similar problem, my persistence.xml is now:

                    <?xml version="1.0" encoding="UTF-8"?>
                    
                    <persistence>
                     <persistence-unit name="MovieDataSource">
                     <provider>
                     org.hibernate.ejb.HibernatePersistence
                     </provider>
                     <jta-data-source>
                     java:/MovieDataSource
                     </jta-data-source>
                     <properties>
                     <property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactories/em"/>
                     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
                     <property name="hibernate.hbm2ddl.auto" value="create-drop" />
                     </properties>
                     </persistence-unit>
                    </persistence>
                    

                    my components.xml is:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <components xmlns="http://jboss.com/products/seam/components"
                     xmlns:core="http://jboss.com/products/seam/core"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:persistence="http://jboss.com/products/seam/persistence"
                     xsi:schemaLocation=
                     "http://jboss.com/products/seam/core
                     http://jboss.com/products/seam/core-2.0.xsd
                     http://jboss.com/products/seam/components
                     http://jboss.com/products/seam/components-2.0.xsd
                     http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.0.xsd">
                    
                     <core:init jndi-pattern="moviedb/#{ejbName}/local" debug="true"/>
                    
                     <core:manager conversation-timeout="120000"/>
                    
                     <persistence:managed-persistence-context name="em"
                     auto-create="true"
                     persistence-unit-jndi-name="java:/EntityManagerFactories/em"/>
                    
                     <component name="org.jboss.seam.ui.EntityConverter">
                     <property name="entityManager">#{em}</property>
                     </component>
                    
                    </components>
                    


                    I think the entityConverter Pete said I needed to use expects an entity manager to be injected by seam and named entityManager. I have called mine em so I don't have to change too much code, but this means the last component is needed to join the names together.

                    Thanks all for your help,
                    Dave