Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Conversor para h:selectOneMenu

Tentei implementar um conversor para o h:selectOneMenu, mas ainda não deu certo. Pesquisei que para isso teria que implementar o método equals, mas não consegui fazê-lo corretamente. Está da seguinte forma o meu equals implementado na classe modelo Empresa:

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;

        Empresa other = (Empresa) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        }
        return true;
    }
8 respostas

Fellipe posta o seu select one menu, está usando CDI? E posta a classe conversor também

Bom dia Alisson. Não estou usando CDI ainda.

Meu p:selectOneMenu (errei o título desse post colocando h:selectOneMenu):

<p:outputLabel value="Selecione a Empresa:" for="empresa" />
                        <p:selectOneMenu converter="generic"
                            value="#{projetoBean.projeto.empresa}" id="empresa">
                            <f:selectItems value="#{projetoBean.empresas}" var="o"
                                itemLabel="#{o.razaoSocial}" itemValue="#{o}"
                                converter="generic" />
                        </p:selectOneMenu>

Classe Empresa (somente com os métodos reescritos):

@Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are
        // not set
        if (!(object instanceof Empresa)) {
            System.out.println("Não é instância de EMPRESA");
            return false;
        }
        Empresa other = (Empresa) object;
        if ((this.id == null && other.id != null)
                || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.eyeq.pivot4j.analytics.entity.Empresa[id=" + id + "]";
    }

Meu conversor:

@FacesConverter(forClass=Empresa.class, value = "generic")
public class EmpresaConverter implements Converter {

    public Object getAsObject(FacesContext ctx, UIComponent component, String string) {
        if (string == null) {
            System.out.println("string = null");
            return null;
        }
        DAO<Empresa> empresaDao = new DAO<Empresa>(Empresa.class);
        Empresa empresa = null;    

        if ((string != null) && (!string.equals(""))) {
            empresa = empresaDao.buscaPorId(Integer.valueOf(string));
        }
        return empresa;
    }

    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        if (value != null) {
            Empresa cat = (Empresa) value;
            return String.valueOf(cat.getId());
        }
        return null;
    }

    protected void addAttribute(UIComponent component, SampleEntity o) {
        String key = o.getId().toString(); // codigo da empresa como chave neste
                                            // caso
        this.getAttributesFrom(component).put(key, o);
    }

    protected Map<String, Object> getAttributesFrom(UIComponent component) {
        return component.getAttributes();
    }

}

Por fim, o erro que estou recebendo quando seleciono uma empresa no p:selectOneMenu e clico para gravar:

mar 15, 2017 9:03:56 AM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
GRAVE: javax.faces.el.EvaluationException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: br.adv.martinelli.Comprov.modelo.Empresa

Fellipe acho que na sua classe converter tem muito código, eu melhoraria ai, mais a lógica é de cada um kkkk, ta vamos la, concerteza você ta querendo adicionar e quando você clica no botão o erro vem correto? posta a sua classe de adicionar?

E como você não esta usando cdi ainda acho que esse código não ira rolar amigo. posta a sua metodo de adicionar ou salvar ai

Hehe poisé, muita coisa aí que talvez possa arrancar fora.

O método de gravar fica na classe ProjetoBean (no caso, estou criando um projeto no sistema, e preciso de uma empresa, que estão listadas naquele p:selectOneMenu):

public void gravar() {
        System.out.println("Gravando projeto " + this.projeto.getNome());

        DAO<Projeto> dao = new DAO<Projeto>(Projeto.class);

        if (this.projeto.getId() == null) {
            dao.adiciona(this.projeto);
            this.projetos = dao.listaTodos();
        } else {
            dao.atualiza(this.projeto);
        }

        this.projeto = new Projeto();
    }

Pelo que eu estava pesquisando, parece ser um problema de inconsistência no relacionamento bidirecional @ManyToOne e @OneToMany, nos setters que criei para cada lado das entidades. Apenas preciso saber como corrigir hehehe

solução!

Consegui! Alterei o cascade da classe Projeto para o atributo empresa para cascade=CascadeType.MERGEsendo que antes estava em cascade=CascadeType.ALL.

Ficou assim:

@ManyToOne(cascade=CascadeType.MERGE, fetch=FetchType.EAGER)
    private Empresa empresa;

Agora consegui criar o projeto certinho!

Obrigado Alisson pela ajuda e disposição!

Boa mano, isso ai e nois

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software