1 2 Previous Next 17 Replies Latest reply on Jan 28, 2008 7:58 AM by lazar.mihai

    Beginner: Bind SelectOneMenu to @onetoone entity object

    tranquillizer

      Hi, I'm a newbie in jsf / seam and I think I have understand the basics, but now I have a question how to set a related object?
      The case:

      I have an entity Object, Category. The category has a OneToOne relation with another Category object, the parentCategory.

      My entity has the @name("category") annotation.
      The fields are mapped against this object, like:
      <h:inputText value="#{category.categoryName}" />
      <h:inputTextarea value="#{category.categoryDescription}">

      I then want to choose the parent category from a select list, I have:
      <h:selectOneMenu value="#{category.parentCategory}" converter="categoryConverter">
      <f:selectItems value="#{categoryController.allCategoriesParentList}">
      </f:selectItems>
      </h:selectOneMenu>

      I have a List returned from my controller object:
      public List getAllCategoriesParentList() {
      List list = new ArrayList();
      int x = 0;
      for(Category c : allCategories) {
      System.out.println("Rendering " + c.getCategoryName());
      list.add(new SelectItem(c.getId(), c.getCategoryName()));
      }
      return list;
      }
      So I set the list with the categorys names, but there is some things missing, which I cannot figure out how to implement. I guess I can inject the parentCategory object in some way so I dont have to load it from the persistence layer once again!?

      Any help appriciated.
      Thanks in advance

        • 1. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
          nickarls

          Well, if you have a SMPC (as is usually best), you could use a

          public List<Category> getAllCategoriesParentList() {
           return entityManager.createQuery("from Category").getResultList();
          }
          

          (note, code from memory, not guaranteed to compile, but something like that)

          and then just use a
          <h:selectOneMenu value="#{category.parentCategory}">
           <s:selectItems value="#{categoryController.allCategoriesParentList}"/>
           <s:convertEntity/>
          </h:select>
          [/code>
          
          and be sure to override equals() and hashCode() for your entity. And to have a messages tag to catch validation errors.


          • 2. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
            tranquillizer

            Hi,
            new problem when trying to use the convertEntity tag,

            Page:

            <h:selectOneMenu value="#{category.parentCategory}">
             <s:selectItems var="categoryItem" value="#{categoryController.allCategories}" label="#{categoryItem.categoryName}" noSelectionLabel="Parent"/>
             <s:convertEntity/>
             </h:selectOneMenu>
            


            Entity has implemented equals() and hashCode()

            Exception:
            22:33:26,625 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
            java.lang.NullPointerException
             at org.jboss.seam.ui.converter.EntityConverterStore.getEntityManager(EntityConverterStore.java:81)
             at org.jboss.seam.ui.converter.EntityConverterStore.put(EntityConverterStore.java:60)
             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:597)
             at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
             at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
             at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
             at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:38)
             at org.jboss.seam.util.Work.workInTransaction(Work.java:40)
             at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:32)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
             at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
             at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:106)
             at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:155)
             at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:91)
             at org.jboss.seam.ui.converter.EntityConverterStore_$$_javassist_0.put(EntityConverterStore_$$_javassist_0.java)
             at org.jboss.seam.ui.converter.EntityConverter.getAsString(EntityConverter.java:67)
             at org.jboss.seam.ui.converter.PrioritizableConverter.getAsString(PrioritizableConverter.java:67)
             at org.jboss.seam.ui.converter.ConverterChain.getAsString(ConverterChain.java:123)
             at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getFormattedValue(HtmlBasicRenderer.java:469)
             at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOption(MenuRenderer.java:502)
             at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:757)
             at com.sun.faces.renderkit.html_basic.MenuRenderer.renderSelect(MenuRenderer.java:811)
             at com.sun.faces.renderkit.html_basic.MenuRenderer.encodeEnd(MenuRenderer.java:335)
             at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:836)
             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:812)
             at javax.faces.component.UIComponent.encodeAll(UIComponent.java:886)
             at javax.faces.component.UIComponent.encodeAll(UIComponent.java:892)
             at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:577)
             at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)
             at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
             at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
             at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
             at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
             at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
             at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
             at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44)
             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
             at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
             at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
             at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
             at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
             at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
             at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
             at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
             at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
             at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
             at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
             at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
             at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
             at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
             at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
             at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
             at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
             at java.lang.Thread.run(Thread.java:619)
            


            Controller:
            @Stateless
            @Name("categoryController")
            @Scope(ScopeType.SESSION)
            public class CategoryControllerImpl implements CategoryController {
             @PersistenceContext(unitName = "database")
             private EntityManager entityManager;
             private List<Category> allCategories;
             @Out()
             public List<Category> getAllCategories() {
             return entityManager.createQuery("select c FROM Category c").getResultList();
             }
            


            • 3. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
              nickarls

              Are you using a seam managed persistence context?

              • 4. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                tranquillizer

                 

                "nickarls" wrote:
                Are you using a seam managed persistence context?


                No actually I don´t..

                • 5. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                  nickarls

                  You might want to.

                  • 6. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                    tranquillizer

                    I have changed it to use SMPC, but I still do get the same problem. Configuration change is:

                    persistence.xml:

                    <persistence-unit name="test" transaction-type="JTA">
                     <jta-data-source>java:/test-ds</jta-data-source>
                    <properties>
                     <property name="hibernate.hbm2ddl.auto" value="update" />
                     <property name="hibernate.show_sql" value="false" />
                     <property name="hibernate.dialect"
                     value="org.hibernate.dialect.MySQLDialect" />
                     <property name="jboss.entity.manager.factory.jndi.name"
                     value="java:/EntityManagerFactories/test-ds"/>
                     </properties>
                     </persistence-unit>


                    components.xml:

                    <core:managed-persistence-context name="entityManager"
                     auto-create="true"
                     persistence-unit-jndi-name="java:/EntityManagerFactories/test-ds">
                     </core:managed-persistence-context>
                    


                    Controller:
                    @PersistenceContext(unitName = "test")
                     private EntityManager entityManager;
                    


                    • 7. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                      nickarls

                      Just use @In on the entityManager...

                      • 8. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                        tranquillizer

                         

                        "nickarls" wrote:
                        Just use @In on the entityManager...


                        I tried that, but keep getting:

                        01:41:19,656 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
                        org.jboss.seam.RequiredException: @In attribute requires non-null value: categoryController.entityManager

                        • 9. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                          pgmjsd

                           

                          "Interista" wrote:
                          "nickarls" wrote:
                          Just use @In on the entityManager...


                          I tried that, but keep getting:

                          01:41:19,656 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
                          org.jboss.seam.RequiredException: @In attribute requires non-null value: categoryController.entityManager


                          Putting @In on 'entityManager' isn't the whole story. You need to configure the Seam-managed persistence context in components.xml. The Seam docos have a bit on how to do that, or you can look some of the Seam examples.

                          http://docs.jboss.com/seam/latest/reference/en/html/persistence.html#persistence.seam-managed-persistence-contexts



                          • 10. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                            nickarls

                            What version of Seam are you running? Are there any errors in the log from not being able to create the persitence units? In 2.0 the link should be something like

                            a deployed Foo-ds.xml with a

                            <jndi-name>FooDatasource</jndi-name>
                            


                            a persistence.xml with
                            <jta-data-source>java:/FooDatasource</jta-data-source>
                            <property name="jboss.entity.manager.factory.jndi.name" value="java:/FooEntityManagerFactory" />
                            


                            and in components.xml

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


                            Which should give you auto-created SMPC available with just
                            @In private EntityManager entityManager;
                            


                            (and injection into all controllers etc. that use the "entityManager" name)

                            you seem to have some sort of managed-persistence-context in components.xml, although under another namespace?


                            • 11. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                              lazar.mihai

                              To be honest I'm glad you opened up the discussion regarding <h:selectOneMenu ...
                              I'm trying to do something like this

                              <h:selectOneMenu id="idCurs" value="#{cursHome.instance.idcurs}">
                               <s:selectItems value="#{cursList.resultList}" label="#{curs.nume}"
                               var="curs"
                               noSelectionLabel="Alege un curs"
                               />
                               <s:convertEntity />
                               <a:support event="onblur" reRender="idcursDecoration" bypassUpdates="true"/>
                               </h:selectOneMenu>


                              I have StudentHome the student ( generated with seam generate entities), and I want it to return the id of a selected item in the option list.

                              I already did the override on equals and hashCode and read the wiki and other posts on the matter but I don't fully understand how the hole thing is supposed to work.

                              It gets the list from the cursList.resultList. Then when I select an item .. he does what exactly ? he sets the value of var to whatever I say in the <h:selectOneMenu ? or where

                              I would like for it to set the value of the current edited studentHome.instance.idcurs to the value of idcurs from the selected item in the list.. something like binding the label value to curs.nume and the value to curs.idcurs

                              Any suggestions or other ways of accomplishing this ?



                              • 12. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                                nickarls

                                Hmmm, if you have a list of entities, why don't you just bind the selected one to the home.instance?

                                the dropdown with entityconverter + smpc is a handy way of taking a list of entities and having the selected entity inserted into another component. Instead of having to write object -> selectitem -> object conversions yourself.

                                • 13. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                                  lazar.mihai

                                  Can u be a bit more explicit please ?

                                  I only need it to set studentHome.instance.idcurs to the correct value from the dropdown.

                                  Maybe if u do a quick example :)

                                  • 14. Re: Beginner: Bind SelectOneMenu to @onetoone entity object
                                    nickarls

                                    Well, if you bind the entity to studenthome.instance then the id should also be automagically populated, no?

                                    1 2 Previous Next