You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
| Online: | 15 Members of 9400 |
| Forum: Seam Users |
01. Apr 2008, 06:21 America/New_York | Link |
I have a lookup table and corresponding JPA component, and a table with a foreign key to that lookup table. The JPA component for this looks like:
@Entity
@Name("customDataConfiguration")
@Table(name = "custom_data_configuration")
public class CustomDataConfiguration implements Serializable
{
@Id
@Column(name = "custom_data_key")
private String customDataKey;
@ManyToOne
@JoinColumn(name = "custom_data_type_code")
private CustomDataType customDataType;
// ...
}
I have a web page which allows editing of the customDataConfiguration component. In order to allow entry of the customDataType field, I figure the easiest thing to do is make it an h:selectOneMenu, and build the SelectItem array like this:
customDataTypes = new ArrayList<SelectItem>();
List<CustomDataType> cdts = em.createQuery("SELECT cdt FROM CustomDataType cdt").
getResultList();
for (CustomDataType cdt : cdts)
customDataTypes.add(new SelectItem(cdt, cdt.getCustomDataTypeDesc()));
Note, the customDataTypes field is set up as:
@Out(required = false,scope=ScopeType.SESSION)
private List<SelectItem> customDataTypes;
I wasn't really sure if this would work and, so far, it doesn't. I get the following error:
sourceId=selectBranchForm:typeSelection[severity=(ERROR 2), summary=(/admin/editcdconfig.xhtml @23,1
07 value="#{customDataConfiguration.customDataType}": java.lang.IllegalArgumentException: argument t
ype mismatch), detail=(/admin/editcdconfig.xhtml @23,107 value="#{customDataConfiguration.customData
Type}": java.lang.IllegalArgumentException: argument type mismatch)]
Is this just the wrong way to go about this or do I just have a minor error somewhere. If there is a better solution, how does that work?
Thanks, ken clark
I don't know what the errors is, but what I do is to return the List returned by the entityManager directly and use a @Factory to the returned value.
Can you post your facelets page?
Marcell Manfrin Barbacena
Tribunal Regional Eleitoral da Paraíba
+55 (83) 8808-8555
marcell a tre-pb.gov.br
barbacena a gmail.com
Brazil - João Pessoa - PB
Here is the whole thing:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ice="http://www.icesoft.com/icefaces/component" template="../layout/template.xhtml"> <ui:define name="body"> <ice:form id="selectBranchForm"> <h:messages globalOnly="true" styleClass="message"/> <ice:panelGrid id="homePanelGrid" columns="1" columnClasses="leftMenu,leftMenu"> <ice:panelGrid columns="2" columnClasses="rightMenu,leftMenu"> <h:outputLabel for="keyid" value="Key Id: " /> <h:inputText id="keyid" value="#{customDataConfiguration.customDataKey}"/> <h:outputLabel for="typeSelection" value="User Entry Field Type: " /> <h:selectOneMenu id="typeSelection" value="#{customDataConfiguration.customDataType}"> <f:selectItems value="#{customDataTypes}"/> </h:selectOneMenu> <h:outputLabel for="required" value="Required Entry?: " /> <h:selectBooleanCheckbox id="required" value="#{customDataConfiguration.required}" /> <h:outputLabel for="labelentry" value="Label: " /> <h:inputText id="labelentry" value="#{customDataConfiguration.customDataLabel}"/> <h:outputLabel for="desc" value="Description (hint): " /> <h:inputTextarea id="desc" rows="4" cols="80" value="#{customDataConfiguration.customDataDesc}"/> </ice:panelGrid> <ice:panelGrid columns="2" columnClasses="leftMenu,leftMenu"> <h:commandButton value="Save" action="#{customDataAction.save}" styleClass="button" /> <h:commandButton value="Cancel" action="#{customDataAction.cancel}" styleClass="button" /> </ice:panelGrid> </ice:panelGrid> </ice:form> </ui:define> </ui:composition>I don't believe I can just convert customDataTypes to be a List of CustomDataType objects with the f:selectItems as it is now. How would I have to change this?
I forgot to mention that before, the screen did display correctly -- the problem was with save.
Thanks, ken
I'm not sure, but I think you need one of the following:
Hope this helps a little...
Sylvain
I think you need a converter String - CustomDataType, and also you need to use tag if your data is in a List; as I understand it, work with a Map. I have made a page with both cases like this:
... <h:selectOneMenu value="#{alumnoActual.tipoDoc}"> <f:selectItems value="#{manager4.getTiposDoc()}" /> </h:selectOneMenu> ... <h:selectOneMenu value="#{alumnoActual.localidad}" converter="#{localidadesList.converter}"> <s:selectItems value="#{localidades}" noSelectionLabel="----" var="loc" label="#{loc.nombre}" /> </h:selectOneMenu> ...baked by EJB session beans:
@Stateful @Name("manager4") @Scope(ScopeType.SESSION) public class AlumnosMgr4 implements IAlumnosMgr4 { ... public Map<String,String> getTiposDoc() { HashMap<String,String> tiposDoc = new HashMap<String,String>(); for (TiposDoc t : TiposDoc.values()) { tiposDoc.put(t.getDescripcion(),t.name()); } return tiposDoc; } @Stateful @Name("localidadesList") @Scope(ScopeType.APPLICATION) public class LocalidadesList implements ILocalidadesList { @Out private List<Localidad> localidades; @PersistenceContext EntityManager em; @Create public void cargarLocalidades() { localidades = em.createQuery("select l from Localidad l") .getResultList(); } public Converter getConverter() { return new LocalidadConverter(localidades); } @Remove @Destroy public void destroy() { } public List<Localidad> getLocalidades() { return localidades; } }the converter:
public class LocalidadConverter implements Converter { private List<Localidad> localidades; public LocalidadConverter(List<Localidad> lista) { localidades = lista; } public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) { if (arg2==null || arg2.length()==0) return null; long id = Long.valueOf(arg2).longValue(); System.out.println("valor de id: "+arg2); if (id<0) return null; Localidad lRet = null; for (Localidad l : localidades) { if (l.getIdlocalidad()==id) { lRet = l; break; } } return lRet; } public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) { if (arg2==null) return "-1"; Localidad l = (Localidad)arg2; System.out.println("Localidad: "+l.getNombre()); return String.valueOf(l.getIdlocalidad()); } }hope this helps
Ernesto Cullen