O que é um converter?
Um converter pode ser uma classe java que implemente javax.faces.converter.Converter ou pode-se utilizar tags do próprio jsf
Vou tentar explicar como eu conseguir resolver o problema,
No momento de salvar os dados, o que esta na pagina web são string´s ou seja texto, então o JSF precisa converter isto para objetos então por isto ele chama um conversor, então ele ( o conversor ) deve ser implementado.
o conversor serve tanto no momento de carregar os dados para a pagina, quanto no momento de obter os dados da pagina
para salvar. Para salvar devera ser chamado um método getAsObject
vamos passo a passo então vou começar das classes entidade usando um exemplo de Municipio e Estado
trecho de codigo da classe Municipio.Java mostrando o relacionamento
//bi-directional many-to-one association to Estado
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id_estado")
private Estado estado;
Estado.java
//Observe o metodo toString porque ele será necessário
@Id
@Column(name="id_estado")
private String idEstado;
@Column(name="ds_estado")
private String dsEstado;
//bi-directional many-to-one association to Municipio
@OneToMany(mappedBy="estado")
private List<Municipio> municipios;
@Override
public String toString() {
return dsEstado;
}
Vamos agora ver como esta a minha pagina, note que ela chama um metodo estadoC.itemsAvailableSelectOne
“estadoC” é o meu MB
<h:outputLabel for="nome" value="Nome:" />
<h:inputText id="nome" value="#{municipioC.municipio.dsMunicipio}" style=" width : 450px;"/>
<h:outputLabel for="estado" value="Uf:" />
<h:selectOneMenu id="estado" value="#{municipioC.municipio.estado}" >
<f:selectItems value="#{estadoC.itemsAvailableSelectOne}"
var="item"
itemValue="#{item}"
itemLabel="#{item.dsEstado}" />
</h:selectOneMenu>
EstadoController.java
@ManagedBean(name="estadoC")
@SessionScoped
public class EstadoController {
private Estado estado;
private List<Estado> estadoLista;
private int totalRegistros;
@ManagedProperty(value = "#{estadoService}")
private EstadoService estadoService;
public SelectItem[] getItemsAvailableSelectOne() {
return FacesUtil.getSelectItems(estadoService.findAll(), true);
}
@FacesConverter(forClass = Estado.class)
public static class EstadoControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
EstadoController controller = (EstadoController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "estadoC");
return controller.estadoService.findByID(getKey(value));
}
so para não ficar duvidas vamos ver o metodo getSelectItems na classe FacesUtil
observe a variavel X que será o objeto Estado e x.toString() será a descricao do estado ( veja na classe Estado.java )
FacesUtil.java
public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
int size = selectOne ? entities.size() + 1 : entities.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (selectOne) {
items[0] = new SelectItem("", "---");
i++;
}
for (Object x : entities) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}