Как правильно повторно прикрепить отдельные объекты в Hibernate? - PullRequest
177 голосов
/ 27 мая 2009

У меня есть ситуация, в которой мне нужно повторно прикрепить отсоединенные объекты к сеансу гибернации, хотя в сеансе МОЖЕТ уже существовать объект с таким же идентификатором, что приведет к ошибкам.

Прямо сейчас я могу сделать одну из двух вещей.

  1. getHibernateTemplate().update( obj ) Это работает тогда и только тогда, когда объект не существует в сеансе гибернации. Выдаются исключения, указывающие, что объект с данным идентификатором уже существует в сеансе, когда он понадобится мне позже.

  2. getHibernateTemplate().merge( obj ) Это работает, если и только если объект существует в сеансе гибернации. Исключения генерируются, когда мне нужно, чтобы объект был в сеансе позже, если я использую это.

Учитывая эти два сценария, как я могу в общем случае присоединять сеансы к объектам? Я не хочу использовать исключения для управления потоком решения этой проблемы, так как должно быть более элегантное решение ...

Ответы [ 15 ]

1 голос
/ 19 октября 2016

для повторного присоединения этого объекта, вы должны использовать merge ();

этот метод принимает в качестве параметра, что ваша сущность отсоединена, и возвращает сущность, будет присоединена и загружена из базы данных.

Example :
    Lot objAttach = em.merge(oldObjDetached);
    objAttach.setEtat(...);
    em.persist(objAttach);
1 голос
/ 24 февраля 2011

В оригинальном сообщении есть два метода, update(obj) и merge(obj), которые упоминаются как работающие, но в противоположных обстоятельствах. Если это действительно так, то почему бы не проверить, находится ли объект сначала в сеансе, а затем вызвать update(obj), если это так, иначе вызвать merge(obj).

Тест на существование в сеансе session.contains(obj). Поэтому я думаю, что будет работать следующий псевдокод:

if (session.contains(obj))
{
    session.update(obj);
}
else 
{
    session.merge(obj);
}
1 голос
/ 28 мая 2009

попробуйте getHibernateTemplate (). Replicate (entity, ReplicationMode.LATEST_VERSION)

0 голосов
/ 05 января 2011

вызов сначала merge () (для обновления постоянного экземпляра), а затем блокировки (LockMode.NONE) (для присоединения текущего экземпляра, а не возвращаемого функцией merge ()), кажется, работает для некоторых случаев использования.

0 голосов
/ 27 мая 2009
try getHibernateTemplate().saveOrUpdate()
...