Problema para excluir Contato [Resolvido]

7 respostas
iuoyo

Boa tarde,

Estou aqui postando pois não achei nada parecido tanto no google como no Fórum.

Estou desenvolvendo uma aplicação com JSF + RichFaces + JPA.

Coloquei um dataTable fazendo uma listagem de contatos e um botão excluir para excluir o contato. Porém ao clicar no botão ele da essa exception (StackPrace abaixo):

java.lang.IllegalArgumentException: Entity must be managed to call remove: br.edu.ufabc.jpa.model.Contact[pkContact=3], try merging the detached and try the remove again.
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.performRemove(UnitOfWorkImpl.java:3582)
        at org.eclipse.persistence.internal.jpa.EntityManagerImpl.remove(EntityManagerImpl.java:435)
        at br.edu.ufabc.jpa.manager.ContactManager.delete(ContactManager.java:56)
        at br.edu.ufabc.faces.UserFaces.removeContact(UserFaces.java:35)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.el.parser.AstValue.invoke(AstValue.java:191)
        at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
        at org.apache.jasper.el.JspMethodExpression.invoke(JspMethodExpression.java:68)
        at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
        at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
        at javax.faces.component.UICommand.broadcast(UICommand.java:315)
        at org.ajax4jsf.component.UIDataAdaptorBase.broadcast(UIDataAdaptorBase.java:1387)
        at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:329)
        at org.ajax4jsf.component.AjaxViewRoot.broadcastEventsForPhase(AjaxViewRoot.java:304)
        at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:261)
        at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:474)
        at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
        at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
        at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
        at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:619)

Muitos falam que é preciso dar um merge() com o JPA pra depois usar o remove(). Acredito que essa não seria uma solução correta. Outra tópico vi que se tiver uma Foreign Key em cascata na opção de deletar, ele cancela o flush e para a opção de remove() do JPA. Alterei e nada.

Essa é meu JPA para remover o contato.

public boolean delete(Contact contact) {
        try {
            manager.getTransaction().begin();
            manager.remove(contact);
            manager.flush();
            manager.getTransaction().commit();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            manager.getTransaction().rollback();
            return false;
        }
    }

Agradeço a Atenção desde Já!

7 Respostas

josemanzoli

Cara coloca também sua Entidade e o Managed Bean.

iuoyo

Essa aqui é a Entidade que manipula o Contato.

package br.edu.ufabc.jpa.manager;

import br.edu.ufabc.jpa.model.Contact;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class ContactManager {

    private EntityManager manager;

    public ContactManager() {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("ContatoJPAPU");
        manager = factory.createEntityManager();
    }

    public boolean create(Contact contact) {
        try {
            manager.getTransaction().begin();
            manager.persist(contact);
            manager.flush();
            manager.getTransaction().commit();
            return true;
        } catch (Exception e) {
            manager.getTransaction().rollback();
            return false;
        }
    }

    public Contact read(Contact contact) {
        return manager.find(Contact.class, contact.getPkContact());
    }

    public Contact read(Integer idContact) {
        return manager.find(Contact.class, idContact);
    }

    public boolean update(Contact contact) {
        try {
            manager.getTransaction().begin();
            manager.merge(contact);
            manager.flush();
            manager.getTransaction().commit();
            return true;
        } catch (Exception e) {
            manager.getTransaction().rollback();
            return false;
        }
    }

    public boolean delete(Contact contact) {
        try {
            manager.getTransaction().begin();
            manager.remove(contact);
            manager.flush();
            manager.getTransaction().commit();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            manager.getTransaction().rollback();
            return false;
        }
    }

    public List<Contact> list(Integer idUser) {
        try {
            List<Contact> contacts = null;
            Query q = manager.createQuery("select c from Contact c where c.user.pkUser = :value");
            q.setParameter("value", idUser);
            contacts = q.getResultList();
            return contacts;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Esse é o Managed Bean da Aplicação

package br.edu.ufabc.faces;

import br.edu.ufabc.jpa.manager.ContactManager;
import br.edu.ufabc.jpa.manager.UserManager;
import br.edu.ufabc.jpa.model.Contact;
import br.edu.ufabc.jpa.model.Mail;
import br.edu.ufabc.jpa.model.Phone;
import br.edu.ufabc.jpa.model.User;

public class UserFaces {

    private User user;
    private String login;
    private String password;
    private Contact selectedContact;
    private Phone selectedPhone;
    private Mail selectedMail;

    public UserFaces() {
        user = new User();
        login = new String();
        password = new String();
        selectedContact = new Contact();
        selectedPhone = new Phone();
        selectedMail = new Mail();
    }

    public String sair() {
        limpar();
        return "goToLogin";
    }

    public String removeContact() {
        ContactManager contactManager = new ContactManager();
        boolean teste = contactManager.delete(selectedContact);
        if (teste) {
            System.out.println("\n\n\n\nDeu Certo");
        } else {
            System.out.println(selectedContact.getPkContact());
            System.out.println("\n\n\n\nDeu Errado");
        }
        user.setContactList(contactManager.list(user.getPkUser()));
        return "goToMain";
    }

    public String efetuarLogin() {
        UserManager userManager = new UserManager();
        user = userManager.read(login);

        if (user != null) {
            if (user.getVchUserPassword().equals(password)) {
                ContactManager contactManager = new ContactManager();
                user.setContactList(contactManager.list(user.getPkUser()));
                return "goToMain";
            } else {
                limpar();
                return "goToLogin";
            }
        } else {
            limpar();
            return "goToLogin";
        }
    }

    public String limparLogin() {
        user = new User();
        login = new String();
        password = new String();
        selectedContact = new Contact();
        selectedPhone = new Phone();
        selectedMail = new Mail();
        return "goToLogin";
    }

    public void limpar() {
        user = new User();
        login = new String();
        password = new String();
        selectedContact = new Contact();
        selectedPhone = new Phone();
        selectedMail = new Mail();
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Contact getSelectedContact() {
        return selectedContact;
    }

    public void setSelectedContact(Contact selectedContact) {
        this.selectedContact = selectedContact;
    }

    public Mail getSelectedMail() {
        return selectedMail;
    }

    public void setSelectedMail(Mail selectedMail) {
        this.selectedMail = selectedMail;
    }

    public Phone getSelectedPhone() {
        return selectedPhone;
    }

    public void setSelectedPhone(Phone selectedPhone) {
        this.selectedPhone = selectedPhone;
    }
}
josemanzoli

Chama seu método “read” antes de dar o delete que vai funcionar. Seu contato tá fora do contexto você precisa achar ele antes.

mals aí…

segue

public  boolean delete(Contact contact) {  
         try {  
             manager.getTransaction().begin();
             manager.remove(manager.read(contact));  
             manager.flush();  
             manager.getTransaction().commit();  
             return true;  
         } catch (Exception e) {  
             e.printStackTrace();  
             manager.getTransaction().rollback();  
             return false;  
         }  
     }
iuoyo

Valeu josemanzoli. Era uma coisa tão boba só que para quem não tem prática me matei.

O que significa “fora de contexto”?

josemanzoli

Um pouquinho complicado para eu te explicar sem desenhar! Ehehhehehehe… eu não sou muito bom para explicar esse tipo de coisa sem exemplos gráficos.

Já esse povo aqui tem uma explicação muito melhor que a minha…

http://blog.caelum.com.br/2006/11/23/entidades-managed-transient-e-detached-no-hibernate-e-jpa/

iuoyo

Ótimo.

Vou da uma olhada em casa. Aqui na faculdade essa página tá bloqueada.

De qualquer forma, grade muito a atenção. Abraços!
[Tópico Resolvido]

josemanzoli

Tipo mais ou menos é assim.

O contexto de persistência tem os objetos abertos nele, aí se você tenta acessar um objeto que não está mais aberto no contexto (que é o seu caso) ele fica meio doidão e se perde, aí você indica para o contexto onde o seu objeto está e ele vai inserir dentro do contexto novamente!..

Não sei se consegui mas depois que você ler o link que passei você vai entender!

bons estudos aí!

Criado 20 de outubro de 2010
Ultima resposta 20 de out. de 2010
Respostas 7
Participantes 2