Erro com remove da JPA! Entity detached! help!

4 respostas
Javabuntu

Pessoal não sei mais o que realizar… todas vez que vou dar um remove ele diz que a Entity ta detached, SENDO que eu já mandei ela num em.merge…

java.lang.IllegalArgumentException: Removing a detached instance

estou usando hibernate com jpa, uso tmb spring…
veja como está e pq não executa…
estou chamando assim:

MvacFacade instance =(MvacFacade)context.getBean("mvacFacade"); //obtenho o bean pelo spring
Mvac mvac = instance.carregar(codigo_projeto); // carrego o objeto pelo codigo.... uso o objeto normal...

aqui em outro momento quero excluir

Mvac mvac = instance.gravar(mvac); // o gravar chama o facade que vai chamar o DAO pra dar o merge
instance.excluir(mvac); // chama facade pra depois ir remove

minha facade que chama a DAO

public Mvac gravar(Mvac mvac) { 
        return getMvacDao().gravar(mvac); //chama o merge
  }

 public void excluir(Mvac mvac) { 
    	getMvacDao().excluir(mvac);  // chama o remove
  }

aqui estão minhas DAO’s

public Mvac gravar(Mvac mvac) throws DataAccessException {
        return em.merge(mvac);
    }

    public void excluir(Mvac mvac) throws DataAccessException {
       em.remove(mvac);
    }

o problema é, eu chamo o merge pro objeto pra deixar estado gerenciado, mas quando vou remover ele está detached
aqui era pra ser normal, o gravar realiza o merge da entity…

Mvac mvac = instance.gravar(mvac); // o gravar chama o facade que vai chamar o DAO pra dar o merge
instance.excluir(mvac); // chama facade pra depois ir remove, mas AQUI diz que está detached...

obs: por exemplo, minha entity PESSOA está assim e FUNCIONA. não há erro de compilador nem nada, estou usando o JUnit pra testes…

vlw a todos, Hewerton

4 Respostas

Paulo_Silveira

Ola!

realmente esta estranho!

coloque o codigo do seu dao. ele esta abrindo um entity manager novo a cada invocacao de granularidade fina? voce nao esta usando open session in view?

Javabuntu

tenho uma única Entity Manager que está sendo injetada pelo spring…

por enquanto estou fazendo minhas classes de negócios, minhas Dao’s, Facade’s, já diz a view da aplicação mas ainda não estou integrando, estou realizando testes JUnit pra depois tudo testado e funcionando eu ligar com minhas view…

basicamente meu Dao está assim:

import com.virtual.Model.Mvac;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Hewerton
 */
@Repository
@Transactional
public class MvacDao{
    
    @PersistenceContext
    private EntityManager em;
    
    /** Creates a new instance of ArtefatoDao */
    public MvacDao() {
   }
    
    public void persiste(Mvac mvac) throws DataAccessException {
         em.persist(mvac);
      }
    
    public void atualizar(Mvac mvac) throws DataAccessException {
         em.refresh(mvac);
      }  
      
    public Mvac gravar(Mvac mvac) throws DataAccessException {
        return em.merge(mvac);
    }

    public void excluir(Mvac mvac) throws DataAccessException {
      em.remove(mvac);
    }

vlw Hewerton

Paulo_Silveira

está estranho. quase certeza que o manager não é o mesmo não, e que a cada lookup o spring está te injetando um novo.

verifique isso logando a referência ao entity manager para descobrir se é a mesma

reolca

Vi que a Thread está no ar faz um tempo, mas o problema ocorre porque o objeto passado para o método merge não é o mesmo que é anexado a sessão.

O método merge retorna o objeto que ele anexou, então para o seu código dar certo você teria que dar um jeito de colocar a seguinte idéia no seu código (por exemplo, se fosse um objeto do tipo Banco que deve ser anexado a sessão da JPA):

public void alterar(Banco banco) {

    // Código simplificado sem iniciar transação e tal...

    Banco _banco = em.merge(banco); // Note que o objeto passado como parâmetro não é o mesmo que o retornado.
    em.remove(_banco); // Objeto que o método merge retornou é que deve ser removido.

}

Abração.

Criado 1 de fevereiro de 2008
Ultima resposta 25 de out. de 2008
Respostas 4
Participantes 3