Dúvida no Hibernate: O que significa essa exceção NonUniqueObjectException?

Salve rapaziada.

Seguinte, estou quebrando a cabeça a horas e não achei a solução até agora. :(.

Quando faço uma pesquisa(all) e depois tento remover ou alterar algum registro acontece a seguinte exceção.

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.rodrigo.stp.bean.PessoaBean#81]
	at org.hibernate.engine.PersistenceContext.checkUniqueness(PersistenceContext.java:549)
	at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:72)
	at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:527)
	at br.com.rodrigo.stp.infra.generics.AbstractGenericPersistenceHibernateDao.delete(AbstractGenericPersistenceHibernateDao.java:177)

a different object with the same identifier value was already associated with the session

Alguém sabe como resolver???

O esquisito é que consigo executar o crud normalmente via main acontece esse erro quando uso via web(usando struts).

Obrigado.

Sem mais, Rodrigo.

Voce implementou o equals e o hascode desta classe?

Não tinha implementado mas já acabei de implementar e continua o mesmo erro(NonUniqueObjectException), tem mais alguma alternativa?

Obrigado.

Sem mais, Rodrigo.

Qdo vc vai remover ou alterar vc cria um pojo e popula ele ou pega um objeto q veio do banco mesmo. Já passei por esta exceção e acontecia qdo ia alterar ou remover um objeto q tava no banco, mas o meu problema era q eu criava um pojo para popular coms os dados q vinham do banco.

Se num for isso , posta o código relevante. (entre as tags code)

Cara essa excecao acontece qdo vc possui duas referencais a um mesmo objeto ( errrrrrrrrrr ), calma deixa eu explicar…
essa execao 'e muuuito util… pq evita redundancia, o q acontece 'e que no seu codigo vc possui um objeto q pode ser acessado via o relacionamento de outro, sem a necessidade de uma outra busca no banco, mas vc insiste em fazer outra busca, qdo o hibernate ve q vc poderia pegar o objeto pelo relacionamento e mesmo assim fez outra busca ele lanca essa porcaria ai…
se tiver mais duvidas estou a diposicao…
flw…

Também estou com este problema, mas é quando tento dar um saveOrUpdate. Já tentei fechar a session do Hibernate mas mesmo assim não está funcionando

usa merge pra resolver esse problema:

getHibernateTemplate().merge()

:roll:

[quote=deniswsrosa]Cara essa excecao acontece qdo vc possui duas referencais a um mesmo objeto ( errrrrrrrrrr ), calma deixa eu explicar…
essa execao 'e muuuito util… pq evita redundancia, o q acontece 'e que no seu codigo vc possui um objeto q pode ser acessado via o relacionamento de outro, sem a necessidade de uma outra busca no banco, mas vc insiste em fazer outra busca, qdo o hibernate ve q vc poderia pegar o objeto pelo relacionamento e mesmo assim fez outra busca ele lanca essa porcaria ai…
se tiver mais duvidas estou a diposicao…
flw…[/quote]

Está acontecendo comigo este erro, na seguinte situação:

Tenho uma Lista de Opções com checkbox e cada linha tem mais 3 checkbox:

[]Opcao A []I []U []D
[]Opcao B []I []U []D

Quando marco uma Opção faço um Insert e ao marcar I, U ou D faço um Update. mas para fazer um update, tenho que buscar o ID da opção marcada.

public void processaPermissoes(Profile_Security profile_security){
	if(profile_security.getId_profile_security() == 0){
		this.profile_security = this.daoFactory.getProfile_SecurityDao().loadRegistro(profile_security);
		profile_security.setId_profile_security(this.profile_security.getId_profile_security());
	}
	this.daoFactory.beginTransaction();
	this.daoFactory.getProfile_SecurityDao().altera(profile_security);
	this.daoFactory.commit();
}

Como posso resolver este erro ?

Grato.

[RESOLVIDO]

Coloquei um SESSION FLUSH antes do update, que sincroniza o estado dos objetos alterados com o estado dos dados da tabela e um SESSION CLEAR.

public void altera(T u){
	this.session.flush();
	this.session.clear();
	this.session.update(u);
}

A sincronizacao eh opcional…

public String saveModel(){
		try {			 
			session.clear();
			session.saveOrUpdate(model);
			tx.commit();
		}catch(Exception e) {
			tx.rollback();
			e.printStackTrace();
		}
		return null;
	}

Att,

Resolvi isso localizando uma outra referência a minha entidade. Usei o session.evict(entidade) . Pois a entidade estava pendurada no cache com o mesmo valor.

vlw

ou voce pode usar o merge, que nao lanca essa exception, pois nao colocara o dado objeto no first level cache!
é bom usar o merge por ele ser especificado pela JPA, ja o update nao é. assim voce vai se acostumando.

[color=red]a different object with the same identifier value was already associated with the session:[/color]
Após tentar …

			session.evict(obj);			
			session.flush();
			session.clear();
			session.setCacheMode(CacheMode.IGNORE);

Resolvi o problema usando o merge …

//Método velho que tava gerando Exceção
	public void save(T obj) 
		throws FlorencaException{
		
		Session session         = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		
		try {			
			
			transaction.begin();
			session.save(obj);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
			throw new FlorencaException
				(FlorencaException.getMensagem(e));				
		}
		finally {
			session.close();
		}
	}

// Método novo funcionando ... 

	@Override
	public void save(CepCidadeVO obj) 
		throws FlorencaException{
		
		Session session         = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		
		try {						
			System.out.println("CepCidadeDAO.save()");
			transaction.begin();
			session.merge(obj);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
			throw new FlorencaException
				(FlorencaException.getMensagem(e));				
		}
		finally {
			session.close();
		}
	}

Obrigado ! :roll:

Estou com este erro também, mas na inclusão, ou save().
Tenho uma tabela A e para cada item desta tabela, gravo 100 itens na tabela B, então o que eu quero fazer é mais ou menos isso:

daoFactory.beginTransaction();
ObjetoA objA = new ObjetoA();
...
objA.save(); //para simplificar
for (int i = 0; i < 100; i++) {
  ObjetoB objB = new ObjetoB();
  ...
  ojbB.save(); //simplificando...
}
daoFactory.commit();

Pelo jeito não é possível fazer deste modo. Alguém teria alguma sugestão para que o commit() só se dê após a gravação de todos os objetos na tabelaB?

[]'s

Galera,

estava com esse mesmo problema utilizando o JBoss Seam.
Anotei a PK com @GeneratedValue(strategy = GenerationType.IDENTITY) nos meus beans e o tipo das variáveis (de primitivo para objeto) e tudo se resolveu.

espero ter ajudado

bramorim, estava com esse problema também usando o JBOSS e sua dica resolveu :slight_smile:
obrigada

poww…estou com o mesmo problema só que no meu caso é em um “delete”, então a solução do merge não serviria…


for (RetornoExameTemp retornoExameTemp : dataListRetorno) {
					RetornoExameTempDAOFactory.getDAO().delete(retornoExameTemp);
				}

e o erro…

br.com.is.commons.db.dao.InfrastructureException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [br.com.is.isenterprise.lab.model.RetornoExameTemp#Empresa=1, Paciente=1072, No. Sequência=2No. Sequência Exame=2Id. Retorno=258]
at br.com.is.commons.db.dao.DAOImplHb.delete(Unknown Source)

Bem Estou com o mesmo problema…

Esse é o codigo que estou tendo esse dor de cabeça…

package common.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.hibernate.Transaction;

public class TxInterceptor implements InvocationHandler {

private Object target;

private TxInterceptor(Object target) {
	this.target = target;
}

@SuppressWarnings("unchecked")
public static Object newProxy(Object target) {
	Class clazz = target.getClass();
	return Proxy.newProxyInstance(clazz.getClassLoader(), clazz
			.getInterfaces(), new TxInterceptor(target));
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
		throws Throwable {
	
	Transaction transaction = HibernateUtil.getSession().getTransaction();

	try {
		[b]transaction.begin();
		Object result = method.invoke(this.target, args);
		transaction.commit();
		return result;[/b]

	} catch (InvocationTargetException e) {
		transaction.rollback();
		throw e.getCause();

	} catch (Exception e) {
		transaction.rollback();
		throw e;

	}
}

}

Usei o merge mais não funcionou… se alguem puder me ajudar Fico grato!
:slight_smile:

[b]
Eu tb estava com o mesmo problema para fazer a persistencia eu usei MERGE , ok.
Mais problema era ao fazer o DELETE dava esse erro abaixo:

delete a different object with the same identifier value was already associated with the session:

PROBLEMA RESOLVIDO
[/b]

	public List pesquisarPagamentoHb(PlanoPagamento planoPagamento) throws DAOException {
		Query query = null;
		Session sessions = null;
		List pagamentoList = new ArrayList<PlanoPagamento>();
		if(planoPagamento.getPesquisar() != ""){
			sessions = HbLocator.currentSession();
			try {
				query = sessions.createQuery(
					" FROM PlanoPagamento " +
					" WHERE "+planoPagamento.getFiltro()+" like ? " )
					.setString(0, planoPagamento.getPesquisar()+"%");
				pagamentoList = query.list();       
			} catch (Exception e) {
				e.printStackTrace();
				throw new DAOException("[PagamentoDAOImpl - pesquisarPagamentoHb] " + e.getMessage(), e);
			}
		}
		HbLocator.closeSession(); 
		return  pagamentoList;
		
	}

[quote=deniswsrosa]Cara essa excecao acontece qdo vc possui duas referencais a um mesmo objeto ( errrrrrrrrrr ), calma deixa eu explicar…
essa execao 'e muuuito util… pq evita redundancia, o q acontece 'e que no seu codigo vc possui um objeto q pode ser acessado via o relacionamento de outro, sem a necessidade de uma outra busca no banco, mas vc insiste em fazer outra busca, qdo o hibernate ve q vc poderia pegar o objeto pelo relacionamento e mesmo assim fez outra busca ele lanca essa porcaria ai…
se tiver mais duvidas estou a diposicao…
flw…[/quote]

Eu estou com o mesmo problema .
Como que agente corrige esse problema ?

[quote=lynddinha]usa merge pra resolver esse problema:
getHibernateTemplate().merge()
[/quote]

lynddinha muito obrigado o merge realmente resolveu meu problema de NonUniqueObjectException :lol: