Help

Controls

PermLinkWikiLink

Built with Seam

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.

Forum: Seam Users Forum ListTopic List
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

4 Replies:
01. Apr 2008, 07:07 America/New_York | Link

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 cache 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

01. Apr 2008, 13:12 America/New_York | Link

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

01. Apr 2008, 14:40 America/New_York | Link

I'm not sure, but I think you need one of the following:

  • a custom converter to convert from String to CustomDataType
  • a setCustomDataType(String s) method that accept a String and convert it, then store the value to your customDataType field (possibly annotating this method with @In)

Hope this helps a little...
Sylvain

01. Apr 2008, 16:21 America/New_York | Link

I think you need a converter String - CustomDataType, and also you need to use s:selectItems tag if your data is in a List; as I understand it, f:selectItems 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