Pessoal, bom dia.
Estou querendo obter a instancia de um Session Bean em um Converter do Jsf, mas estou tendo problemas quanto a isso.
A princípio estava utilizando o annotation @EJB para buscar essa instância(não funcionou), depois vi que tinha que obter esse recurso através de um lookup.
Olhei alguns exemplos e ainda assim não estou conseguindo a instância. Segue abaixo o código. Alguém pode ajudar?
O SessionBean
@Stateless(name = "EstadoRepository")
public class EstadoRepository extends GenericRepository<Estado>{
O converter que precisa da instância
[code]@FacesConverter(forClass = Estado.class, value=“estadoConverter”)
public class EstadoConverter implements Converter{
private EstadoRepository getSession() {
try {
return (EstadoRepository) new InitialContext().lookup("EstadoRepository");
} catch (Exception ex) {
ex.printStackTrace();
throw new SisCgException("Não foi possível obter o lookup de EstadoRepository para EstadoConverter");
}
} [/code]
Pode fazer assim:
No web.xml do seu WAR:
<ejb-local-ref>
<ejb-ref-name>ejb/EstadoRepository</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.seupacote.EstadoRepository</local>
</ejb-local-ref>
Pegar a referência:
InitialContext ctx = new InitialContext();
EstadoRepository estadoRepository = (EstadoRepository) ctx.lookup("java:comp/env/ejb/EstadoRepository");
Uma dica para você, caso queira um converter genérico é usar o do xpert-framework:
http://showcase.xpertsistemas.com.br/xpert-showcase-war/views/components/entityConverter.jsf
A vantagem é que não feita uma nova consulta no banco de dados. Fazendo de maneira braçal você teria que criar um converter para cada entidade.
Cara funcionou sim, muito obrigado!
Cara, acredito que agora o problema está ou no converter ou na maneira que estou passando meu objeto. Pois estou obtendo o seguinte erro:
Alguém pode ajudar a identificar o erro? Sei que o hibernate chega a realizar a consulta e também traz registros.
java.lang.ClassCastException: java.lang.String cannot be cast to br.com.pactotecnologia.entity.Estado
esse erro está estourando quando entra na 1ª linha do método getAsString declarado conforme a seguir:
[code]@FacesConverter(forClass = Estado.class, value = “estadoConverter”)
public class EstadoConverter implements Converter {
private EstadoRepository getSession() {
try {
EstadoRepository estadoRepository = (EstadoRepository) initialContext.lookup("java:comp/env/ejb/EstadoRepository");
return estadoRepository;
} catch (Exception ex) {
ex.printStackTrace();
throw new SisCgException("Não foi possível obter o lookup de EstadoRepository para EstadoConverter");
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String id) {
if (id != null && !id.equals("")) {
try {
Estado estadoRetorno = this.getSession().pesquisaPorId(Long.parseLong(id));
return estadoRetorno;
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
Estado estado = (Estado) value;
return estado.getId() + "";
}
}[/code]
A chamada no xhtml
<p:selectOneMenu id="enderecoEstadoSelect" style="width:300px"
value="#{clienteBean.estado}">
<f:selectItem itemValue="" itemLabel="Selecione..." noSelectionOption="true"/>
<f:selectItems value="#{clienteBean.listaEstados}" var="estado" itemLabel="#{estado}"/>
<f:converter converterId="estadoConverter"/>
<p:ajax update="enderecoCidadeSelect" />
</p:selectOneMenu>
E os valores são obtidos de ClienteBean, através do método:
public List<Estado> getListaEstados(){
return this.estadoRepository.pesquisarTodos();
}
Deu uma olhada no cenverter genérico que te mandei?
Acho que precisa de uma verificação do nulo:
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || "".equals(value)){
return "";
}
Estado estado = (Estado) value;
return estado.getId() + "";
}
Se não dé certo muda o selectItens e adiciona o itemValue:
<f:selectItems value="#{clienteBean.listaEstados}" var="estado" itemLabel="#{estado}" itemValue="#{estado}"/>
Era sim, estava fazer validações de valores null no converter. Só que agora não estou conseguindo salvar meu objeto final. Na hora do submit com o botão salvar, apenas um dos valores do selectOneMenu da o seguinte erro somente na tela: Cidade: Erro de validação: o valor não é válidoCidade: Erro de validação: o valor não é válido. Tendo em vista que faço o mesmo com o selectOneMenu de Estado e não ocorre o erro.
Fui debugar o converter do dois e o método getAsObject é chamado três vezes onde, a primeira vem com o id do obejto, a segunda e a terceira vem uma String vazia.
Ta difícil encontrar o erro desses combos.
Segue o código.
Converter
[code]@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value != null && (!value.equals(“Selecione…”) && !value.equals(""))){
Cidade cidade = this.getSession().pesquisaPorId(Long.parseLong(value));
return cidade;
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value != null && value instanceof Cidade){
Cidade cidade = (Cidade) value;
return cidade.getId() + "";
}
return null;
}[/code]
xhtml
[code]<h:panelGrid>
<p:outputLabel value=“Estado” for=“enderecoEstadoSelect” />
<p:selectOneMenu id=“enderecoEstadoSelect” style=“width:300px"
required=“true” converter=“estadoConverter"
value=”#{clienteCadastroBean.estado}”>
<f:selectItem itemLabel=“Selecione…” itemValue="" />
<f:selectItems value="#{clienteCadastroBean.listaEstados}“
var=“estado” itemLabel=”#{estado.nome}" itemValue="#{estado}" />
<p:ajax update=“enderecoCidadeSelect” />
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid>
<p:outputLabel value="Cidade" for="enderecoCidadeSelect" />
<p:selectOneMenu id="enderecoCidadeSelect" style="width:300px"
required="true" converter="cidadeConverter"
value="#{clienteCadastroBean.cidade}">
<f:selectItem itemLabel="Selecione..." itemValue="" />
<f:selectItems value="#{clienteCadastroBean.listaCidades}"
var="cidade" itemLabel="#{cidade.nome}" itemValue="#{cidade}" />
</p:selectOneMenu>
</h:panelGrid>[/code]
gets e sets do meu bean
[code]public List getListaEstados() {
return this.estadoRepository.pesquisarTodos();
}
public List<Cidade> getListaCidades() {
if (estado != null && estado.getId() != null) {
return this.cidadeRepository.pesquisarCidadesPorEstado(this.estado);
}
return new ArrayList<Cidade>();
}[/code]
Verifica se a entidade tem equals e hashcode (pelo id) implemetados.
Cara, minha entidade realmente tava sem o equals. Obrigado pela sua ajuda.