[RESOLVIDO] Problema ao deletar objeto de uma lista

7 respostas
f2pro

Pessoal, estou com um sério problema
estou usando o primefaces 2.1 com JSF 2.0
e, numa dataTable onde eu clico na linha, ele passa para um objeto contato_selecionado e depois, ao clicar em remover ocorre algo estranho.

suponhamos que tenha 3 contatos, selecione qualquer um deles sempre o primeiro é o excluido… porém… se eu der ou system.out.printLn(this.contato_selecionado.getNome()); por exemplo ele lista o nome do objeto que eu realmente selecionei…

segue abaixo o código…

contatos.xhtml

<?xml version='1.0' encoding='UTF-8' ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets">

    <script type="text/javascript" >
        function gerenciaJanela(xhr, status, args){
            if(args.fechar == true){
                dialog_contatos.hide();
                document.forms['contato'].reset();
            }
        }
    </script>

    <ui:include src="../includes/head.xhtml"/>
    <h:body>
        <f:view contentType="text/html">
            <ui:include src="../includes/cabecalho.xhtml"/>
            <p:messages id="msgCadastro" />
            <div id="conteudo">
                <h:form id="form">
                    <p:tabView effect="opacity" effectDuration="normal">
                        <p:tab title="Dados Pessoais">
                            <p:commandButton
                                value="Novo Contato"
                                update="contato:cadastro_contato contato:cadastro_contato"
                                action="#{cadastroContatosMB.reinitContato}"
                                onclick="dialog_contatos.show();"/>
                            <hr />

                            <p:outputPanel id="lista_contatos">
                                <p:dataTable value="#{cadastroContatosMB.lista_contatos}" 
                                             var="con"
                                             selection="#{cadastroContatosMB.contato_selecionado}"
                                             selectionMode="single"                                             
                                             emptyMessage="Nenhum contato cadastrado"
                                             loadingMessage="Carregando contatos">
                                    <f:facet name="header">
                                        Contatos Cadastrados
                                    </f:facet>
                                    <p:column width="156">
                                        <f:facet name="header">
                                            <h:outputText value="cargo"/>
                                        </f:facet>
                                        <h:outputText value="#{con.cargo}"/>
                                    </p:column>
                                    <p:column width="335">
                                        <f:facet name="header">
                                            <h:outputText value="Nome"/>
                                        </f:facet>
                                        <h:outputText value="#{con.nome}"/>
                                    </p:column>
                                    <p:column>
                                        <f:facet name="header">
                                            <h:outputText value="Nascimento"/>
                                        </f:facet>
                                        <h:outputText value="#{con.data_aniversario}"/>
                                    </p:column>
                                    <p:column width="195">
                                        <f:facet name="header">
                                            <h:outputText value="Email"/>
                                        </f:facet>
                                        <h:outputText value="#{con.email}"/>
                                    </p:column>
                                </p:dataTable>
                                <p:commandButton action="#{cadastroContatosMB.deletaContato}"
                                                 update="lista_contatos lista_contatos contato:dialog_contatos contato:dialog_contatos"
                                                 value="Remover"/>

                            </p:outputPanel>
                        </p:tab>
                    </p:tabView>
                </h:form>
                <h:form id="contato">
                    <p:dialog header="Cadastro de Contatos" widgetVar="dialog_contatos" id="dialog_contatos" width="500" closable="true" draggable="false" resizable="false" closeOnEscape="false">
                        <p:panel id="cadastro_contato" widgetVar="cadastro_contato">
                            <p:messages id="erros"/>
                            <h:panelGrid columns="2">

                                <h:outputLabel value="Cargo :"/>
                                <h:inputText id="cargo_contato"
                                             maxlength="50"
                                             value="#{cadastroContatosMB.contato.cargo}"
                                             style="width: 300px;"/>

                                <h:outputLabel value="Nome :"/>
                                <h:inputText id="nome_contato"
                                             value="#{cadastroContatosMB.contato.nome}"
                                             maxlength="100"
                                             style="width: 300px;"/>

                                <h:outputLabel value="Nascimento :"/>
                                <p:calendar value="#{cadastroContatosMB.aniversario}"
                                            pattern="dd/MM/yyyy" />

                                <h:outputLabel value="Email :"/>
                                <h:inputText id="email_contato"
                                             value="#{cadastroContatosMB.contato.email}"
                                             maxlength="100"

                                             style="width: 300px;"/>

                                <h:outputLabel value="MSN :"/>
                                <h:inputText id="msn_contato"
                                             value="#{cadastroContatosMB.contato.msn}"
                                             maxlength="100"

                                             style="width: 300px;"/>

                                <h:outputLabel value="Telefone :"/>
                                <p:inputMask value="#{cadastroContatosMB.contato.telefone}"
                                             mask="([telefone removido]"
                                             id="telefone_contato"
                                             style="width: 300px;"/>

                                <h:outputText/>


                                <p:commandButton value="Adicionar"
                                                 action="#{cadastroContatosMB.insereContato}"
                                                 oncomplete="gerenciaJanela(xhr, status, args);"
                                                 update="form:lista_contatos form:lista_contatos">
                                </p:commandButton>

                            </h:panelGrid>
                        </p:panel>
                    </p:dialog>
                </h:form>
            </div>
        </f:view>
    </h:body>
</html>

e o CadastroContatosMB.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mb;

import beans.Contato;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.context.RequestContext;

/**
 *
 * @author F2PRO
 */
@ManagedBean
@SessionScoped
public class CadastroContatosMB implements Serializable {

    /** Creates a new instance of CadastroContatosMB */
    private Contato contato_selecionado = new Contato();
    private Contato contato = new Contato();
    private List<Contato> lista_contatos = new ArrayList<Contato>();
    private Date aniversario = new Date();

    public List<Contato> getLista_contatos() {
        return lista_contatos;
    }

    public void setLista_contatos(List<Contato> lista_contatos) {
        this.lista_contatos = lista_contatos;
    }

    public Contato getContato_selecionado() {
        return contato_selecionado;
    }

    public void setContato_selecionado(Contato contato_selecionado) {
        this.contato_selecionado = contato_selecionado;
    }

    public Contato getContato() {
        return contato;
    }

    public void setContato(Contato contato) {
        this.contato = contato;
    }

    public Date getAniversario() {
        return aniversario;
    }

    public void setAniversario(Date aniversario) {
        this.aniversario = aniversario;
    }
    
    public String insereContato() {
        lista_contatos.add(contato);
        reinitContato();
        RequestContext requestContext = RequestContext.getCurrentInstance();
        requestContext.addCallbackParam("fechar", true);
        //this.contato_selecionado = null;
        return null;
    }

    public String deletaContato() {
        if(lista_contatos.remove(this.contato_selecionado)){
            System.out.println("deletado com sucesso");
        }
        return null;
    }

    public String reinitContato() {
        contato = new Contato();
        
        return null;
    }

    public CadastroContatosMB() {
    }
}

7 Respostas

B

Sua classe Contato implementa o método “equals” corretamente?

f2pro

creio que sim cara…
ele foi gerado automaticamente com o hibernate …

B

f2pro:
creio que sim cara…
ele foi gerado automaticamente com o hibernate …

Me parece que o método “List.remove()” está usando o método “Object.equals()” para determinar a igualdade entre os objetos de Contato no momento da remoção, por isso o comportamento inesperado.

Você deve sobrescrever o método em Contato.

f2pro

brrodo:
f2pro:
creio que sim cara…
ele foi gerado automaticamente com o hibernate …

Me parece que o método “List.remove()” está usando o método “Object.equals()” para determinar a igualdade entre os objetos de Contato no momento da remoção, por isso o comportamento inesperado.

Você deve sobrescrever o método em Contato.

segue abaixo o meu equals…

@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 Contato)) { return false; } Contato other = (Contato) object; if ((this.codigo_contato == null && other.codigo_contato != null) || (this.codigo_contato != null && !this.codigo_contato.equals(other.codigo_contato))) { return false; } return true; } [/quote]

f2pro

Pessoal… já resolvi
com as pistas que me deram… eu criei outro equals… dai comparando campo a campo, nao todos até agora…

segue o codigo a baixo…

public boolean equalsFields(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Contato)) { return false; } Contato other = (Contato) object; if ((this.codigo_contato != other.codigo_contato ) || (!this.cargo.equals(other.cargo)) || (!this.data_aniversario.equals(other.data_aniversario))){ return false; } return true; }

alguem sabe de outro modo mais efetivo? caso tenha vários campos…
abraços…

B

f2pro:
brrodo:
f2pro:
creio que sim cara…
ele foi gerado automaticamente com o hibernate …

Me parece que o método “List.remove()” está usando o método “Object.equals()” para determinar a igualdade entre os objetos de Contato no momento da remoção, por isso o comportamento inesperado.

Você deve sobrescrever o método em Contato.

segue abaixo o meu equals…

@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 Contato)) { return false; } Contato other = (Contato) object; if ((this.codigo_contato == null && other.codigo_contato != null) || (this.codigo_contato != null && !this.codigo_contato.equals(other.codigo_contato))) { return false; } return true; }

[/quote]

Cheque se o atributo “codigo_contato” do “contato_selecionado” não está null.

Eu colocaria um breakpoint no método “equals” da classe Contato e debugaria para ver se o comportamento dele está adequado.

Esse problema não tem a ver com o JSF, tem a ver com o método “List.remove” q não consegue identificar qual objeto da lista é igual ao objeto “contato_selecionado” q é passado como parâmetro para removê-lo.

B

f2pro:
Pessoal… já resolvi
com as pistas que me deram… eu criei outro equals… dai comparando campo a campo, nao todos até agora…

segue o codigo a baixo…

public boolean equalsFields(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Contato)) { return false; } Contato other = (Contato) object; if ((this.codigo_contato != other.codigo_contato ) || (!this.cargo.equals(other.cargo)) || (!this.data_aniversario.equals(other.data_aniversario))){ return false; } return true; }

alguem sabe de outro modo mais efetivo? caso tenha vários campos…
abraços…

Pra definir a igualdade, vc precisa sobrescrever tanto o método “hashcode()” quanto “equals()” da classe Object.

Geralmente se vc gerou o hashcode utilizando apenas o atributo “id” da classe, vc implementa o “equals” utilizando apenas esse mesmo atributo. Ou seja, utilize os mesmos atributos pra definir tanto o hashcode qt a igualdade pelo método “equals”.

Eu colocaria o atributo “codigo_contato” como “int” e usaria uma implementaçaõ mais simples:

public boolean equals(Object o) { 
    if ((o instanceof Contato) && (((Contato)o).codigo_contato
    == this.codigo_contato)) {
        return true;
    } else {
        return false;
    }
}
Criado 27 de janeiro de 2011
Ultima resposta 27 de jan. de 2011
Respostas 7
Participantes 2