Eu tenho dois objetos de usuário e enquanto tento salvar o objeto usando
session.save(userObj);
Eu estou recebendo o seguinte erro:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
Estou criando a sessão usando
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(),
BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close(); // in finally block
Eu também tentei fazer o session.clear()
antes de salvar, ainda sem sorte.
Esta é a primeira vez que estou obtendo o objeto de sessão quando chega uma solicitação do usuário, então estou entendendo por que está dizendo que o objeto está presente na sessão.
Alguma sugestão?
Respostas:
Já tive esse erro muitas vezes e pode ser muito difícil rastreá-lo ...
Basicamente, o que o hibernate está dizendo é que você tem dois objetos que possuem o mesmo identificador (mesma chave primária), mas não são o mesmo objeto.
Eu sugiro que você divida seu código, ou seja, comente os bits até que o erro desapareça e, em seguida, coloque o código de volta até que ele volte e você encontre o erro.
Na maioria das vezes acontece por salvamento em cascata, onde há um salvamento em cascata entre o objeto A e B, mas o objeto B já foi associado à sessão, mas não está na mesma instância de B que o de A.
Qual gerador de chave primária você está usando?
A razão de eu perguntar é que esse erro está relacionado a como você está dizendo ao hibernate para verificar o estado persistente de um objeto (ou seja, se um objeto é persistente ou não). O erro pode estar acontecendo porque o Hibernate está tentando persistir um objeto que já é persistente. Na verdade, se você usar o save, o hibernate tentará persistir esse objeto, e talvez já exista um objeto com a mesma chave primária associada à sessão.
Exemplo
Supondo que você tenha um objeto de classe de hibernação para uma tabela com 10 linhas com base em uma combinação de chave primária (coluna 1 e coluna 2). Agora, você removeu 5 linhas da tabela em algum momento. Agora, se você tentar adicionar as mesmas 10 linhas novamente, enquanto o hibernate tenta persistir os objetos no banco de dados, 5 linhas que já foram removidas serão adicionadas sem erros. Agora, as 5 linhas restantes que já existem, irão lançar esta exceção.
Então a abordagem mais fácil seria verificar se você atualizou / removeu algum valor de uma tabela que faz parte de algo e mais tarde você está tentando inserir os mesmos objetos novamente
fonte
Este é apenas um ponto em que a hibernação causa mais problemas do que resolve. No meu caso existem muitos objetos com o mesmo identificador 0, pois são novos e não possuem nenhum. O db os gera. Em algum lugar eu li que 0 sinais não foram definidos. A maneira intuitiva de persisti-los é iterar sobre eles e dizer hibernar para salvar os objetos. Mas você não pode fazer isso - "É claro que você deve saber que hibernar funciona desta e daquela maneira, portanto, você deve ..." Portanto, agora posso tentar alterar os Ids para Longos em vez de longos e ver se funciona. No final, é mais fácil fazer isso com um mapeador simples por conta própria, porque hibernar é apenas um fardo intransparente adicional. Outro exemplo: Tentar ler parâmetros de um banco de dados e persisti-los em outro força você a fazer quase todo o trabalho manualmente.
fonte
Uso
session.evict(object);
A função deevict()
método é usada para remover a instância do cache de sessão. Portanto, para salvar o objeto pela primeira vez, salve-o chamando osession.save(object)
método antes de remover o objeto do cache. Da mesma forma, atualize o objeto chamandosession.saveOrUpdate(object)
ousession.update(object)
antes de chamar evict ().fonte
Isso pode acontecer quando você usa o mesmo objeto de sessão para leitura e gravação. Quão? Digamos que você tenha criado uma sessão. Você lê um registro da tabela de funcionários com a chave primária Emp_id = 101 Agora você modificou o registro em Java. E você vai salvar o registro do funcionário no banco de dados. não fechamos sessão em nenhum lugar aqui. Como o objeto que foi lido também persiste na sessão. Ele está em conflito com o objeto que desejamos escrever. Daí vem esse erro.
fonte
Como alguém já apontou acima, encontrei esse problema quando tinha as
cascade=all
duas pontas de umone-to-many
relacionamento, então vamos supor A -> B (um para muitos de A e muitos para um de B) e estava atualizando a instância de B em A e, em seguida, chamando saveOrUpdate (A), estava resultando em uma solicitação de salvamento circular, ou seja, salvamento de A aciona salvamento de B que aciona salvamento de A ... e na terceira instância como a entidade (de A) foi tentada ser adicionado a sessionPersistenceContext a exceção duplicateObject foi lançada.Eu poderia resolver isso removendo a cascata de uma extremidade.
fonte
Você pode usar
session.merge(obj)
, se estiver fazendo save com diferentes sessões com o mesmo objeto persistente identificador.Funcionou, eu tive o mesmo problema antes.
fonte
Também tive esse problema e tive dificuldade em encontrar o erro.
O problema que tive foi o seguinte:
O objeto foi lido por um Dao com uma sessão de hibernação diferente.
Para evitar essa exceção, simplesmente releia o objeto com o dao que salvará / atualizará este objeto posteriormente.
tão:
Espero que isso economize muito tempo para algumas pessoas!
fonte
Encontrei este problema por:
Resolvi esvaziando os resultados após a exclusão e limpando o cache antes de salvar o novo objeto
fonte
Esse problema ocorre quando atualizamos o mesmo objeto da sessão, que usamos para buscar o objeto do banco de dados.
Você pode usar o método de mesclagem de hibernação em vez do método de atualização.
por exemplo, primeiro use session.get () e então você pode usar session.merge (objeto). Este método não criará nenhum problema. Também podemos usar o método merge () para atualizar o objeto no banco de dados.
fonte
Pegue o objeto dentro da sessão, aqui um exemplo:
fonte
Seus mapeamentos de ID estão corretos? Se o banco de dados é responsável por criar o Id por meio de um identificador, você precisa mapear seu objeto de usuário para esse.
fonte
Eu encontrei este problema com a exclusão de um objeto, nem despejar nem limpar ajudou.
fonte
antes da posição onde os objetos repetitivos começam, você deve fechar a sessão e então você deve iniciar uma nova sessão
portanto, desta forma em uma sessão não há mais de uma entidade com o mesmo identificador.
fonte
Atrasado para a festa, mas pode ajudar para os próximos usuários -
Eu tenho esse problema quando seleciono um registro usando
getsession()
e atualizo novamente outro registro com o mesmo identificador usando a mesma sessão que causa o problema. Código adicionado abaixo.Isso nunca deve ser feito. A solução é remover a sessão antes da atualização ou alterar a lógica de negócios.
fonte
Verifique se você esqueceu de colocar @GenerateValue para a coluna @Id. Eu tive o mesmo problema com muitos para muitos relacionamentos entre Filme e Gênero. O programa lançou Erro de Hibernate: org.hibernate.NonUniqueObjectException: um objeto diferente com o mesmo valor de identificador já estava associado ao erro de sessão. Descobri depois que só preciso ter certeza de que você tem @GenerateValue para o método de obtenção GenreId.
fonte
apenas verifique o id se leva nulo ou 0 como
em adicionar ou atualizar onde o conteúdo é definido do formulário para Pojo
fonte
Eu sou novo no NHibernate, e meu problema é que usei uma sessão diferente para consultar meu objeto da que usei para salvá-lo. Portanto, a sessão de salvamento não sabia sobre o objeto.
Parece óbvio, mas lendo as respostas anteriores, eu estava procurando em todos os lugares por 2 objetos, não 2 sessões.
fonte
@GeneratedValue (strategy = GenerationType.IDENTITY), adicionar esta anotação à propriedade da chave primária em seu bean de entidade deve resolver esse problema.
fonte
Eu resolvi esse problema.
Na verdade, isso está acontecendo porque esquecemos a implementação do tipo de gerador da propriedade PK na classe do bean. Então faça de qualquer tipo como
quando persistimos os objetos do bean, todos os objetos adquirem o mesmo ID, então o primeiro objeto é salvo, quando outro objeto a ser persistido então o HIB FW através deste tipo de
Exception: org.hibernate.NonUniqueObjectException:
objeto diferente com o mesmo valor de identificador já estava associado à sessão.fonte
O problema ocorre porque na mesma sessão de hibernação você está tentando salvar dois objetos com o mesmo identificador. Existem duas soluções: -
Isso está acontecendo porque você não configurou seu arquivo mapping.xml corretamente para os campos de id conforme abaixo: -
Sobrecarregue o método getsession para aceitar um parâmetro como isSessionClear e limpe a sessão antes de retornar à sessão atual como abaixo
Isso fará com que os objetos de sessão existentes sejam apagados e mesmo que o hibernate não gere um identificador único, assumindo que você configurou seu banco de dados corretamente para uma chave primária usando algo como Auto_Increment, ele deve funcionar para você.
fonte
Eu tive um problema parecido. No meu caso, esqueci de definir o
increment_by
valor no banco de dados para ser igual ao usado porcache_size
eallocationSize
. (As setas apontam para os atributos mencionados)SQL:
Java:
fonte
Ao contrário do que wbdarby disse, pode até acontecer quando um objeto é buscado fornecendo o identificador do objeto a um HQL. No caso de tentar modificar os campos do objeto e salvá-lo novamente no BD (modificação pode ser inserir, excluir ou atualizar) na mesma sessão , este erro aparecerá. Tente limpar a sessão de hibernação antes de salvar o objeto modificado ou crie uma nova sessão.
Espero ter ajudado ;-)
fonte
Eu tenho o mesmo erro ao substituir meu conjunto por um novo obtido de Jackson.
Para resolver isso, mantenho o conjunto existente, removo do conjunto antigo o elemento desconhecido para a nova lista com
retainAll
. Em seguida, adiciono os novos comaddAll
.Não há necessidade de ter a Sessão e manipulá-la.
fonte
Experimente isso. O abaixo funcionou para mim!
No
hbm.xml
arquivoPrecisamos definir o
dynamic-update
atributo da tag de classe paratrue
:Defina o atributo de classe da tag do gerador na coluna exclusiva para
identity
:Observação: defina a coluna exclusiva como em
identity
vez deassigned
.fonte
Outra coisa que funcionou para mim foi tornar a variável de instância Long no lugar de long
Eu tinha minha variável de chave primária long id; alterando-o para Long id; trabalhou
Muito bem sucedida
fonte
Você sempre pode fazer um flush de sessão. Flush irá sincronizar o estado de todos os seus objetos na sessão (por favor, alguém me corrija se eu estiver errado), e talvez isso resolveria o seu problema em alguns casos.
Implementar seus próprios equals e hashcode também pode ajudá-lo.
fonte
Você pode verificar as configurações do Cascade. As configurações de Cascade em seus modelos podem estar causando isso. Eu removi as configurações do Cascade (essencialmente não permitindo inserções / atualizações do Cascade) e isso resolveu meu problema
fonte
Eu também encontrei esse erro. O que funcionou para mim foi ter certeza de que a chave primária (que é gerada automaticamente) não é um PDT (ou seja, longo, int, ect.), Mas um objeto (ou seja, Long, Integer, etc.)
Ao criar seu objeto para salvá-lo, certifique-se de passar null e não 0.
fonte
Isso ajuda?
fonte
Resolvi um problema semelhante como este:
fonte