Org.hibernate.NonUniqueObjectException [RESOLVIDO]

9 respostas
T

Como é do conhecimento de todos, essa exceção é lançada quando vc
tentar associar 2 instancias da mesma classe e com a mesma PK em uma
mesma Session.

Eu estou utilizando Struts + Hibernate, e utilizando um FilterServlet que abre
e fecha uma Session pra todas as requisições seguindo o OSIV.

O código que esta causando o erro é:

Produto produto = (Produto) servletRequest.getSession().getAttribute("produtoBean");
 HibernateUtil.getSession().lock(produto, LockMode.NONE);

 int codClienteConcorrente = Integer.parseInt(servletRequest.getParameter("codClienteConcorrente"));
 ClienteConcorrente clienteConcorrente = (ClienteConcorrente) HibernateDefaultDAO.getInstance().getById(codClienteConcorrente, ClienteConcorrente.class);

 HibernateUtil.beginTransaction();
 produto.delClienteConcorrente(clienteConcorrente);
 HibernateUtil.commitTransaction();

A lançada quando é executado o commit é:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.interativati.sigv.cliente.ClienteConcorrente#1]

Bom se no momento que o JSP termina de ser renderizado o FilterServlet fecha a Session, quando o formulário solicita a execução dessa Action está Session não possui nenhum objeto associado a ela, contúdo só existiria um objeto clienteConcorrente associado a ela.

9 Respostas

T

someone please :cry:

T

Pessoal,

Também estou tendo esse erro, mas quando eu faço um UPDATE.
Utilizando Struts + Hibernate + javax.servlet.Filter + MySQL.

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [sistema.nucleo.Nucleo#5]
	at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:556)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:259)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:217)
	at org.hibernate.event.def.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:33)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
	at org.hibernate.impl.SessionImpl.fireUpdate(SessionImpl.java:566)
	at org.hibernate.impl.SessionImpl.update(SessionImpl.java:554)
	at org.hibernate.impl.SessionImpl.update(SessionImpl.java:546)
	at sistema.hibernate.HibernateGenericDAO.update(HibernateGenericDAO.java:29)
	at sistema.nucleo.NucleoDAO.update(NucleoDAO.java:19)
	at sistema.nucleo.NucleoUpdateAction.execute(NucleoUpdateAction.java:51)
	at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:398)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
	at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1062)
	at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestProcessor.java:263)
	at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:386)
	at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(TilesRequestProcessor.java:318)
	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:229)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at sistema.MyFilter.doFilter(MyFilter.java:48)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
	at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:833)
	at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:639)
	at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1285)
	at java.lang.Thread.run(Unknown Source)
O parte do código que indica o erro é:
HibernateUtility.getSession().update(objeto);

O objeto passado no parâmetro é o objeto nucleo

Toda ajuda é bem vinda!
Agradeço...

T

Sergio,

No seu caso é o seguinte:

Se vc esta tentando dar um update, vc teve de fazer um load() ou get() para o Hibernate fazer o retrieve. Quando executa um save()/update() ele tenta associar o objeto a HS, e certamente este mesmo objeto ou outro com a mesma PK ja esta associada a HS.

exemplificando:

como deve estar:
-> get() objeto
-> inicia transacao
-> altera objeto
-> update() // ERRADO, pq o como a sessao não foi fechada ela ja esta associado, e não precisa de update().
-> manda commitar

correto:
-> get() objeto
-> inicia transacao
-> altera objeto
-> manda commitar

se vc fecha a sessão seria:
-> get() objeto
-> fecha sessao
-> altera objeto
-> inicia transacao
-> update() objeto // isso vai re-associalo a Sessão, nesse caso esta correto pq como sessao foi fechada, não existe outro associado
-> manda commitar

T

tralala,

Funcionou beleza a sua dica, e bem mais simples do que eu estava implementando!

Como estou usando Filtro, só fiz colocar na Action que dá Update:
O get do objeto Nucleo a ser modificado
Set nos campos a serem modificados e pronto!
O begin e o commit da transação e o close da session é feita pelo Filtro.

Valeu ae pela dica!

T

nads :slight_smile:
agora só falta eu resolver o meu objeto-fantasma huaeuhea :evil:

mardito! :wink:

M

O que é que essa linha faz?

produto.delClienteConcorrente(clienteConcorrente);
T

Maurício,

Ele percorre o Set clienteConcorrente e remove o objeto passado
via parametro do Set.

public void delClienteConcorrente(ClienteConcorrente clienteConcorrente) {
        if(this.clienteConcorrente != null) {
            Iterator it = this.clienteConcorrente.iterator();
            while(it.hasNext()) {
                ClienteConcorrente cc = (ClienteConcorrente) it.next();
                if(clienteConcorrente.getId() == cc.getId()) {
                    this.clienteConcorrente.remove(clienteConcorrente);
                    break;
                }
            }
        }
    }
T

resolvido modificando:

this.clienteConcorrente.remove(clienteConcorrente);

para

this.clienteConcorrente.remove(cc);

sem mais!
8)

K
tralala,

estou com o mesmo problema que o seu, porém eu não entendi o método que vc criou: delClienteConcorrente(ClienteConcorrente clienteConcorrente), vc poderia me explicar??

Estou fazendo um método generico então ele está assim:

protected Serializable save(Object obj) throws HibernateEsception{

Transaction t = null;

Session s = null;

try{

s = getSession();

t = beginTransaction(s);

Serializable rtn = save(obj,s);

t.commit();

return rtn;

}catch(HibernateException e){

throw e;

}finally{

closeSession();

}

}

Obrigada, no aguardo

Criado 30 de junho de 2006
Ultima resposta 17 de out. de 2007
Respostas 9
Participantes 4