Skip to end of metadata
Go to start of metadata

Selecting from a list of entities

See http://docs.jboss.org/seam/latest/reference/en/html/controls.html

  • Use <s:selectItems> to produce a list of labeled select items from a list of entities.
  • Use <s:convertEntity> to map back and forth between the select items and the actual entity values. This is what allows you to map the value of the <h:selectOneMenu> directly to the property of the referencing entity (e.g. a property that is a many-to-one).
  1. person is an entity that has been outjected into the conversation. It has a 'continent' property which is many-to-one association with another entity.
  2. continents is a Seam application framework 'query' object. This 'query' object should probably use a Seam-managed EntityManager because we want have the Hibernate session-in-view behavior so we don't get lazy initialization exceptions when rendering the labels, etc.
  3. s:convertEntity will convert the Continent entities into values for the HTML select, and vice versa.

Tips

  1. To avoid LazyInitializationExceptions and/or writing extra code in your EJB/Controller bean to initialize objects, use session in view.
  2. For required fields, put required="true" on the selectOneMenu and override javax.faces.component.UIInput.REQUIRED in messages.properties (see Standard Faces Error Messages).

Select from an enum

This works just like selecting an entity, but <s:convertEnum/> is used instead.

XHTML:

EnumLists.java:

  1. person is an entity that has been outjected into the conversation. It has a 'status' property which is an enum.
  2. We need to expose the values of the enum as a list or an array, so we make a stateless POJO component with getters that returns arrays for various enums called enumLists.

Multi-select from an enum

Here we use a selectManyCheckbox.

The enumLists.roleArray method simply returns the list of all possible Role values from the enum:

The Person object might be an Entity with a set of enum Role values, mapped to a simple table as strings (see Hibernate JPA Tips - Collection of primitives):

Unfortunately, Seam's convertEnum can't handle multi selects yet. This example will yield a strange exception:

java.lang.IllegalArgumentException: java.util.List is not an enum type

Luckily, it's very easy to create Custom converter tags with Facelets. Here is the converter class that handles both ordinary enums and multi-selects:

Labels
  1. Aug 26, 2011

    Anonymous

    Could you attach your classes Person and enumLists?? This article is helping me a lot but I still have some problems...

    I have the last case with three tables (person, rel_pers_roles, roles) I have a list<roles> in a selectManyCheckboxand person wich have an attribute list<rel_pers_roles>. I think I'm having problem with the types because I get some exception like roles can not be cast to Enum....

    Thanks in advance

    P.D: If i see that with Person and enumLists is not enough i'll put a more detailed description...

    1. Aug 27, 2011

      In my use case, Role is an enum and Person contains a set of Roles. The collection of Role enum values is persisted using a collection of elements (primitives) JPA mapping. enumLists.roleArray is very similar to the preceeding example. It returns Role.values().

      If in your case, the role object is an entity then the values aren't enums, so this technique doesn't apply. You have to use "selecting from a list of entities", and your list is a JPA query (or something).

  2. Aug 29, 2011

    Anonymous

    I have seen class person... now I know where is my problem... you have a manytomany relationship so Person has SortedSet<Role>but I have a more complex situation... my class Person has a list<RelPersRoles> because I neet to insert in that intermediate table some extra values... (TS_ADD, TS_UPDATE, USER_ADD, USER_UPDATE, OBS....) and if I put a manytomany relationship I can't (or I don't know how) insert that values with manytomany relationship...

    I continue working... many thanks for your support

    1. Aug 29, 2011

      Right. Like I said, I think this has more to do with the fact that your role object is not an enum.