How to bind SelectOneMenu value to object ?
bossdida Jul 18, 2010 6:37 AMHi there,
I'm quite new in Seam and have read some books but I'm still having troubles in implementation.
I want to fetch Occupation entitis with factory method.
Then save Person entity with selected Occupation.
Here are some codes that I'm using.
Person.java
@Entity @Table(name="PersonTbl") public class Person implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String name; private String surname; private Occupation occupation; @Id @GeneratedValue @NotNull public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Length(max = 20) @NotNull public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToOne @JoinColumn(name = "occupationId") public Occupation getOccupation() { return occupation; } public void setOccupation(Occupation occupation) { this.occupation = occupation; } }
Occupation.java
@Entity @Table(name="OccupationTbl") public class Occupation implements Serializable { private static final long serialVersionUID = 1L; private Long Id; private String Name; public void setId(Long id) { Id = id; } @Id @GeneratedValue @NotNull public Long getId() { return Id; } public void setName(String name) { Name = name; } @NotNull @Length(max = 50) public String getName() { return Name; } }
PersonHome.java
@Name("personHome") @Scope(ScopeType.CONVERSATION) public class PersonHome { private static final long serialVersionUID = 1L; private Person person; @In private EntityManager entityManager; @Out(required = false) private List<Occupation> occupationList; private List<SelectItem> oList; @Create @Begin(flushMode=FlushModeType.MANUAL) public void init() { retreiveOccupationList(); } public void setPerson(Person person) { this.person = person; } public Person getPerson() { return person; } @SuppressWarnings("unchecked") @Factory("occupationList") public void retreiveOccupationList() { occupationList = entityManager.createQuery("select o Occupation o").getResultList(); } @End public void savePerson() { entityManager.flush(); } public List<SelectItem> getoList() { if(oList == null) oList = new ArrayList<SelectItem>(); if(occupationList != null && !occupationList.isEmpty()) for(Occupation o : occupationList) oList.add(new SelectItem(o.getId(), o.getName())); return oList; } public void setoList(List<SelectItem> oList) { this.oList = oList; } }
and AddPerson.xhtml
<h:form> <s:decorate id="enterName" template="/layout/edit.xhtml"> <ui:define name="label">Name:</ui:define> <h:inputText id="name" value="#{personHome.person.name}" required="true"/> </s:decorate> <s:decorate id="enterOccupation" template="/layout/edit.xhtml"> <ui:define name="label">Occupation:</ui:define> <h:selectOneMenu value="#{personHome.person.occupation.id}"> <f:selectItems value="#{personHome.oList}"/> </h:selectOneMenu> </s:decorate> <h:commandButton action="#{personHome.savePerson}" value="Save" /> </h:form>
I'm fetching occupation entities wiht factory method and preparing SelectItem list from them for SelectOneMenu during initial request.
I don't want to assign a long or string to person's occupation, thus declare Occupation field in Person entity, implement mapping ManyToOne.
In initil request everything is fine, when enter string for name and select a value from SelectOneMenu and try to save Person, it complains about null occupation of person entity during validation phase.
Isn't it the responsibility of EntityManager to coordinate entitis like Person, Occupation in conversation and set Person's Occupation according to sent SelectOneMenu value ?
It's actually a simple case, but couldn't manage it.
Can anybody help me with that please.
Thanks for any contribution.