1 2 Previous Next 17 Replies Latest reply: Jan 28, 2008 7:58 AM by Mihai Lazar RSS

Beginner: Bind SelectOneMenu to @onetoone entity object

tranquillizer Newbie

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
    Nicklas Karlsson Master

    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 Newbie

    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
    Nicklas Karlsson Master

    Are you using a seam managed persistence context?

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

     

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


    No actually I don´t..

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

    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
    Nicklas Karlsson Master

    Just use @In on the entityManager...

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

     

    "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
    Joshua Davis Expert

     

    "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
    Nicklas Karlsson Master

    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
    Mihai Lazar Newbie

    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
    Nicklas Karlsson Master

    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
    Mihai Lazar Newbie

    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
    Nicklas Karlsson Master

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

1 2 Previous Next