1
resposta

como contornar a NonUniqueObjectException no hibernate?

Olá. tenho um sistema legado, que usa hibernate puro com mapeamento via arquivos "xxx.hbm.xml".

Ocorre que para poucos registros, tudo funcionava muito bem.

Até que ocorreu um determinado momento em que aumentou a quantidade de registros que a gente precisou tratar e os problemas de performance apareceram ao executar um determinado metodo X, q retorna uma lista de um VO e praticamente soh tem consultas. O momento de salvar no banco é feito em outro metodo que recebe essa lista.

No caso, nesse arquivo xml de mapeamento existem mapeamentos com 4 outras classes. Deu para ver nos logs q ao chamar o metodo X, dentro desse metodo é chamado o metodo '.uniqueResult()' q disparou uma query e ao chamar 'findByPK()' disparou outras 3 queries.

Diante desse problema de desempenho, percebi q no metodo X, apenas um ID era necessário e resolvi trocar na DAO por uma query nativa, o que fez reduzir pela metade o tempo de execução do metodo X, mas causou o erro abaixo ao chamar o metodo para salvar/update no banco de dados: " Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: "

Apenas modifiquei na DAO: ao inves de devolver uma instancia de classe Pessoa, devolvi o ID dessa Pessoa (via query nativa) e setei o ID na instancia Pessoa e tudo funcionou certinho, até o erro acima.

Então, estou com algumas duvidas q vou testar durante a semana:

  1. consigo saber em que estado do ciclo de vida a minha instancia estava em determinado momento, tipo "session.getState(instancia)"?
  2. pq deu esse erro? será q se eu devolver um investidor ao invés de um Long do ID resolve?
  3. é possível modificar do jeito q modifiquei p uma query nativa e ainda assim funcionar o save/update?

Caso tenha alguma referencia para eu poder ler sobre uma possivel solução, agradeço.

Obrigado.

1 resposta

Olá!

Pelo que entendi, você está enfrentando o erro NonUniqueObjectException ao tentar salvar ou atualizar um objeto no banco de dados usando o Hibernate. Esse erro ocorre quando o Hibernate detecta que já existe um objeto com o mesmo identificador na sessão atual.

Uma possível solução para esse problema é verificar se o objeto já existe na sessão antes de tentar salvá-lo ou atualizá-lo. Você pode fazer isso usando o método "contains" da classe Session do Hibernate.

Quanto às suas dúvidas:

  1. Infelizmente, não é possível saber em que estado do ciclo de vida a sua instância estava em determinado momento usando o método "session.getState(instancia)". O Hibernate não fornece esse tipo de informação.

  2. O erro NonUniqueObjectException ocorre quando o Hibernate detecta que já existe um objeto com o mesmo identificador na sessão atual. Se você devolver um objeto Pessoa ao invés de um Long do ID, o erro pode continuar ocorrendo se já existir um objeto Pessoa com o mesmo identificador na sessão.

  3. É possível usar uma query nativa e ainda assim salvar ou atualizar objetos no banco de dados usando o Hibernate. No entanto, é importante garantir que o objeto esteja na sessão antes de tentar salvá-lo ou atualizá-lo.

Espero ter ajudado e bons estudos!