JSF + Facelets: alterar objeto agregado em um droplist
Posted on | 9 de June, 2010 | No Comments
Estou fazendo uma prova de conceito com JSF + Facelets + Hibernate, e tive problemas em alterar um objeto agregado em um droplist.
Antes, eu estava somente colocando o código identificador do objeto que queria modificar, e assim ele me dava o erro “org.hibernate.HibernateException: identifier of an instance …”
O código antes era:
<h:selectOneMenu id=”forn” value=”#{NotaFiscalBean.notaFiscal.fornecedor.codFornecedor}” >
<f:selectItems value=”#{NotaFiscalBean.fornecedores}” ></f:selectItems>
</h:selectOneMenu>
Onde #{Bean.notaFiscal.fornecedor.codFornecedor} é o código do objeto agregado e;
#{NotaFiscalBean.fornecedores} é uma lista de objetos do tipo Map (na verdade, SelectItem) com os valores possíveis. E a chave continha o código identificador e o valor, o nome do fornecedor.
O novo código passou a ser:
<h:selectOneMenu id=”forn” converter=”#{NotaFiscalBean.fornecedorConverter}”
value=”#{NotaFiscalBean.notaFiscal.fornecedor}” >
<f:selectItems value=”#{NotaFiscalBean.fornecedores}” ></f:selectItems>
</h:selectOneMenu>
Onde: #{NotaFiscalBean.notaFiscal.fornecedor} é o objeto agregado;
#{NotaFiscalBean.fornecedores} é igual acima, exceto que na chave do mapeamento passei a utilizar os objetos;
#{NotaFiscalBean.fornecedorConverter} é uma classe que implementa a interface javax.faces.convert.Converter
Na implementação de javax.faces.convert.Converter, você precisa implementar os métodos:
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) e;
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2).
Adicionalmente, inclui o construtor que recebe a lista dos possíveis objetos.
Então, a minha classe Converter ficou assim:
package com.renatom.jsf.converter;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import com.renatom.jsf.model.Fornecedor;
public class FornecedorConverter implements Converter {
List <Fornecedor> list;
public FornecedorConverter(List<Fornecedor> fornecedores) {
list = fornecedores;
}
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
if (arg2 == null || arg2.length() == 0)
return null;
long id = Long.valueOf(arg2).longValue();
if (id < 0)
return null;
Fornecedor fornRet = null;
for (Fornecedor forn : list) {
if (forn.getCodFornecedor() == id) {
fornRet = forn;
break;
}
}
return fornRet;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if (arg2==null) return "-1";
Fornecedor forn = (Fornecedor)arg2;
return String.valueOf(forn.getCodFornecedor());
}
}
Fonte: http://seamframework.org/Community/SelectOneMenuAndJPAManyToOne
Comments
Leave a Reply