[RESOLVIDO] Obter Recurso EJB 3.1 em Converter JSF

7 respostas
Fernando_Mateus

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

@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"); 
            
        }  
    }

7 Respostas

A

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.

Fernando_Mateus

Cara funcionou sim, muito obrigado!

Fernando_Mateus

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:
@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() + "";			
	}
}
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();
	}
A

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}"/>
Fernando_Mateus

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
@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;
	}
xhtml
<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>
gets e sets do meu bean
public List<Estado> 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>();
	}
A

Verifica se a entidade tem equals e hashcode (pelo id) implemetados.

Fernando_Mateus

Cara, minha entidade realmente tava sem o equals. Obrigado pela sua ajuda.

Criado 18 de janeiro de 2013
Ultima resposta 25 de jan. de 2013
Respostas 7
Participantes 2