Chave Composta Hibernate - Popular SelectOneMenu com Object utilizando Converter

1 resposta
CLEYSON

Bom Dia Companheiros ...

Estou com problema para entender a lógica aplicada para um selectOneMenu.

Introdução:
selectOneMenu é componente do Primefaces 3.5;
O selectOneMenu é carregado com objetos;
As classes envolvidas no selectOneMenu receberam subscrita de métodos (equals e hashCode)
A pesquisa que popula o objeto do selectOneMenu é realizada a partir de um relaciomento com chave composta (Objeto Projeto e Portifolio);

Sistema:
Hibernate 3.0.1
Glassfish 3.1.2
Primefaces 3.5

Testes com Sucesso!
Quando populo o selectOneMenu com o portifolioDao.consultar() , carregam os dados e o converter funciona adequadamente ...

Teste com Erro!
Quando populo o selectOneMenu a partir da chave composta (Veja o callPortifolioCentroCustoByProjeto) carregam os dados mas o método equals do PortifolioModel sempre retorna false;
Testes: Tentei colocar no converter o dao de relacionamento mapeando todo objeto projetoPortifolioDao.getIdProjetoPortifolio().getPortifolio().getIdPortifolio para getAsString e portifolioDao.getById(new Long(value)) para getAsObject porém sem sucesso ...

Abaixo códigos:

<h:panelGrid columns="2">
                            <h:outputText value="Projeto:" />
                            <p:selectOneMenu id="checkBoxProjeto" value="#{ordemServicoBean.os.projeto}" label="Projeto" filter="true"  style="margin-left: 10px;width: 300px;height: 22px"
                                             filterMatchMode="startsWith" panelStyle="width:315px;" converter="converterProjetoSelectItem" required="true" >
                                <f:selectItem itemLabel="Selecione Projeto" itemValue="" />
                                <f:selectItems value="#{ordemServicoBean.listaProjetos}" var="projeto" itemValue="#{projeto}" itemLabel="#{projeto.nome}"/>
                                <p:ajax process="@this" listener="#{ordemServicoBean.callPortifolioCentroCustoByProjeto}" update="checkBoxPortifolio,checkBoxCentroCusto"/>
                            </p:selectOneMenu>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Item de Contrato (Portifolio):" />
                            <p:selectOneMenu id="checkBoxPortifolio" value="#{ordemServicoBean.os.portifolio}" label="Portifolio" filter="true"  style="margin-left: 10px;width: 300px;height: 22px"
                                             filterMatchMode="startsWith" panelStyle="width:315px;" converter="converterPortifolioSelectItem" required="true" >
                                <f:selectItem itemLabel="Selecione item de Contrato" itemValue="" />
                                <f:selectItems value="#{ordemServicoBean.listaPortifolios}" var="portifolio" itemValue="#{portifolio}" itemLabel="#{portifolio.nome}"/>
                            </p:selectOneMenu>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Centro de Custo:" />
                            <p:selectOneMenu id="checkBoxCentroCusto" value="#{ordemServicoBean.os.centroCusto}" label="Centro Custo" filter="true"  style="margin-left: 10px;width: 300px;height: 22px"
                                             filterMatchMode="startsWith" panelStyle="width:315px;" converter="converterCentroCustoSelectItem" required="true" >
                                <f:selectItem itemLabel="Selecione Centro de Custo" itemValue="" />
                                <f:selectItems value="#{ordemServicoBean.listaCentrosCusto}" var="centroCusto" itemValue="#{centroCusto}" itemLabel="#{centroCusto.nome}"/>
                            </p:selectOneMenu>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Area:" />
                            <p:selectOneMenu id="checkBoxTipoOS" value="#{ordemServicoBean.os.tipo}" label="Tipo de OS" filter="true"  style="margin-left: 10px;width: 300px;height: 22px"
                                             filterMatchMode="startsWith" panelStyle="width:315px;" converter="converterTipoOSSelectItem" required="true" >
                                <f:selectItem itemLabel="Selecione Tipo de OS" itemValue="" />
                                <f:selectItems value="#{ordemServicoBean.listaTipoOrdensServico}" var="tipoOS" itemValue="#{tipoOS}" itemLabel="#{tipoOS.nome}"/>
                                <p:ajax process="@this" listener="#{ordemServicoBean.callStatusByTipoOS}" update="checkBoxStatus"/>
                            </p:selectOneMenu>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Status:" />
                            <p:selectOneMenu id="checkBoxStatus" value="#{ordemServicoBean.os.status}" label="Status" filter="true"  style="margin-left: 10px;width: 300px;height: 22px"
                                             filterMatchMode="startsWith" panelStyle="width:315px;" converter="converterStatusSelectItem" required="true" >
                                <f:selectItem itemLabel="Selecione o Status" itemValue="" />
                                <f:selectItems value="#{ordemServicoBean.listaStatus}" var="status" itemValue="#{status}" itemLabel="#{status.nome}"/>
                                <p:ajax process="@this"/>
                            </p:selectOneMenu>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Codigo Outros:" />
                            <p:inputText label="Codigo Outros" value="#{ordemServicoBean.os.codigoOutros}" style="margin-left: 10px" required="true"/>
                            <p:separator/>
                            <p:separator/>
                            <h:outputText value="Observacao: " />
                            <p:inputTextarea rows="10" cols="40" value="#{ordemServicoBean.os.observacao}" style="margin-left: 10px" />
                        </h:panelGrid>

Método Bean (ViewScoped)

//Comando para popular Portifolio e Centro de Custo a partir do Projeto
    public void callPortifolioCentroCustoByProjeto(){
        //Captura Portifolio e Centro de Custo
        listaProjetosPortifolio.clear();
//        listaProjetosPortifolio = projetoPortifolioDao.consultarByProjeto(os.getProjeto());
//        
//        //Carrega somente Portifolios
//        listaPortifolios.clear();
//        for(ProjetoPortifolio pp: listaProjetosPortifolio){
//            listaPortifolios.add(pp.getIdProjetoPortifolio().getPortifolio());
//        }
//        
        
        listaPortifolios = portifolioDao.consultar();
        //Carrega Centros de Custos
        listaCentrosCusto.clear();
        listaCentrosCusto = centroCustoDao.consultarByProjeto(os.getProjeto());

    }
Converter
@FacesConverter(value="converterPortifolioSelectItem")
public class ConverterPortifolioSelectItem implements Converter { 
    private  PortifolioDao portifolioDao = new PortifolioDaoImpl();
    
    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println("getAsObject");
        if (value != null && !value.isEmpty()) {
            System.out.println("Object PortifolioModel");
            //seu método de pesquisa para trazer uma instância de Projeto
            return portifolioDao.getById(new Long(value));
        }

        return null;    
    }  
    @Override public String getAsString(FacesContext context, UIComponent component, Object object) {
        System.out.println("getAsString");
        if(object!=null && object instanceof PortifolioModel){
            System.out.println("Fez PortifolioModel");
            PortifolioModel portifolioModel = (PortifolioModel) object;  
            return  String.valueOf(portifolioModel.getIdPortifolio());
        }else{
            System.out.println("Nada PortifolioModel");
            return ""; 
        }
          
    }
   
}
Models envolvidos
@Entity
@Table(name="tbl_portifolio")
public class PortifolioModel implements Serializable {
    
    @OneToMany(cascade={CascadeType.ALL},mappedBy="portifolio")
    private Collection<OrdemServicoModel> listOSs;
    
    @Id//Variável de ID no Banco de Dados
    @Column(name="id_portifolio") 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long idPortifolio;
    
    @Column(name="nome",length=100,nullable=false)
    private String nome;
    
    @Column(name="descricao",length=100)
    private String descricao;
 
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @Column(name="data_cadastro",nullable=false)
    private Date dataCadastro;
   
    @Column(name="usuario_cadastro",length=20,nullable=false)
    private String usuarioCadastro;

 //gettters and setters omitidos

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 37 * hash + (int) (this.idPortifolio ^ (this.idPortifolio >>> 32));
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PortifolioModel other = (PortifolioModel) obj;
        if (this.idPortifolio != other.idPortifolio) {
            return false;
        }
        return true;
    }
    
    
   
}
@Entity
@Table(name="tbl_projeto")
public class ProjetoModel implements Serializable {
    
    @OneToMany(cascade={CascadeType.ALL},mappedBy="projeto")
    private Collection<OrdemServicoModel> listOSs;
    
    @OneToMany(cascade={CascadeType.ALL},mappedBy="projeto")
    private Collection<CentroCustoModel> listCentrosCusto;
    
    
    @Id//Variável de ID no Banco de Dados
    @Column(name="id_projeto") 
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long idProjeto;
    
    @Column(name="proprio",nullable=false)
    private boolean proprio;
    
    @Column(name="nome",length=100,nullable=false)
    private String nome;
    
    @Column(name="descricao",length=100)
    private String descricao;
    
    @Column(name="orcamento",nullable=false)
    private double orcamento;
    
    @Column(name="valor_total",nullable=false)
    private double valorTotal;
    
    @Column(name="observacao",length=100)
    private String observacao;
    
    @Column(name="usuario_cadastro",length=20,nullable=false)
    private String usuarioCadastro;
    
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @Column(name="data_cadastro",nullable=false)
    private Date dataCadastro;

    //gettters and setters omitidos

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 61 * hash + (this.nome != null ? this.nome.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ProjetoModel other = (ProjetoModel) obj;
        if ((this.nome == null) ? (other.nome != null) : !this.nome.equals(other.nome)) {
            return false;
        }
        return true;
    }


    
}
@Embeddable
public class ProjetoPortifolioId implements Serializable{
    
    @ManyToOne(fetch = FetchType.LAZY,optional=false)
    private ProjetoModel projeto;
    
    
    @ManyToOne(fetch = FetchType.LAZY,optional=false)
    private PortifolioModel portifolio;

    /**
     * @return the projeto
     */
    public ProjetoModel getProjeto() {
        return projeto;
    }

    /**
     * @param projeto the projeto to set
     */
    public void setProjeto(ProjetoModel projeto) {
        this.projeto = projeto;
    }

    /**
     * @return the portifolio
     */
    public PortifolioModel getPortifolio() {
        return portifolio;
    }

    /**
     * @param portifolio the portifolio to set
     */
    public void setPortifolio(PortifolioModel portifolio) {
        this.portifolio = portifolio;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + (this.projeto != null ? this.projeto.hashCode() : 0);
        hash = 59 * hash + (this.portifolio != null ? this.portifolio.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ProjetoPortifolioId other = (ProjetoPortifolioId) obj;
        if (this.projeto != other.projeto && (this.projeto == null || !this.projeto.equals(other.projeto))) {
            return false;
        }
        if (this.portifolio != other.portifolio && (this.portifolio == null || !this.portifolio.equals(other.portifolio))) {
            return false;
        }
        return true;
    }
@Entity
@Table(name="rel_projeto_portifolio")
public class ProjetoPortifolio  implements Serializable{
    
    @EmbeddedId
    private ProjetoPortifolioId idProjetoPortifolio;
    
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @Column(name="data_cadastro",nullable=false)
    private Date dataCadastro;
   
    @Column(name="usuario_cadastro",length=20,nullable=false)
    private String usuarioCadastro;

    
    /**
     * @return the dataCadastro
     */
    public Date getDataCadastro() {
        return dataCadastro;
    }

    /**
     * @param dataCadastro the dataCadastro to set
     */
    public void setDataCadastro(Date dataCadastro) {
        this.dataCadastro = dataCadastro;
    }

    /**
     * @return the usuarioCadastro
     */
    public String getUsuarioCadastro() {
        return usuarioCadastro;
    }

    /**
     * @param usuarioCadastro the usuarioCadastro to set
     */
    public void setUsuarioCadastro(String usuarioCadastro) {
        this.usuarioCadastro = usuarioCadastro;
    }

    /**
     * @return the idProjetoPortifolio
     */
    public ProjetoPortifolioId getIdProjetoPortifolio() {
        return idProjetoPortifolio;
    }

    /**
     * @param idProjetoPortifolio the idProjetoPortifolio to set
     */
    public void setIdProjetoPortifolio(ProjetoPortifolioId idProjetoPortifolio) {
        this.idProjetoPortifolio = idProjetoPortifolio;
    }
    
}
Esse é o único selectOneMenu que não quer funcionar, não possui caractere especial (somente espaços entre nomes compostos);

Desde já agradeço pela atenção!

1 Resposta

CLEYSON

Bom Dia

O problema foi resolvido invertendo um pouco maneira de pensar, em vez de acessar o objeto que continha as chaves dos dois objetos (Portifolio e Projeto), acessei pelo objeto e fiz um inner join através de HQL.

No problema citado nas mensagens acima, não consigo ver o erro, pois se o relacionamento possui dois objetos poderia realizar restrições na criteria e popular no bean tratando somente os objetos no qual necessitaria.

A única explicação que vejo é que o objeto (Projeto e Portifolio) vindo da classe "ProjetoPortifolio" possui um hashcode diferente que se avaliado individualmente para as classes Projeto e Portifolio geram tal erro.

Solução:

Método Bean
//Comando para popular Portifolio e Centro de Custo a partir do Projeto
    public void callPortifolioCentroCustoByProjeto(){
        //Captura Portifolio e Centro de Custo
        listaProjetosPortifolio.clear();
        listaPortifolios.clear();
        listaPortifolios = portifolioDao.consultarByProjeto(os.getProjeto());
        //Carrega Centros de Custos
        listaCentrosCusto.clear();
        listaCentrosCusto = centroCustoDao.consultarByProjeto(os.getProjeto());

    }
DaoImpl
@Override
    public List consultarByProjeto(ProjetoModel projeto) {
        try{    
            HibernateUtility.beginTransaction();
            
            String hql = "select p from PortifolioModel p, ProjetoPortifolio pp " +
                    "where p.idPortifolio = pp.idProjetoPortifolio.portifolio.idPortifolio and  " + 
                    "pp.idProjetoPortifolio.projeto.idProjeto = :id";
            Query query = HibernateUtility.getSession().createQuery(hql);
            query.setLong("id", projeto.getIdProjeto());
            lista = (List) query.list();
            HibernateUtility.closeSession();
            return lista;
       }catch (HibernateException hibernateException){
            cancel();
            throw hibernateException;            
        }
    }

O converter é o mesmo citado anteriormente ...

Caso alguém consiga explicar ocorrido a informação será bem vinda.

Agradeço a todos que leram o post.

Criado 3 de junho de 2013
Ultima resposta 5 de jun. de 2013
Respostas 1
Participantes 1