Org.hibernate.NonUniqueObjectException [RESOLVIDO]

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.

someone please :cry:

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 é:

[code]HibernateUtility.getSession().update(objeto);

O objeto passado no parâmetro é o objeto nucleo[/code]

Toda ajuda é bem vinda!
Agradeço…

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

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!

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

mardito! :wink:

O que é que essa linha faz?

  produto.delClienteConcorrente(clienteConcorrente);

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;
                }
            }
        }
    }

resolvido modificando:

this.clienteConcorrente.remove(clienteConcorrente);

para

this.clienteConcorrente.remove(cc);

sem mais!
8)

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