Различия между методами сохранения, обновления, saveOrUpdate, слияния в сеансе? - PullRequest
47 голосов
/ 19 сентября 2011

Я новичок в Hibernate и прошел учебник по Hibernate на прошлой неделе.У меня есть несколько сомнений по поводу методов save, update, saveOrUpdate и merge в классе Session.Это:

  • метод сохранения: используется для вставки вновь созданного объекта в хранилище данных.(В основном значение идентификатора будет 0 для этого).Подобно тому, как я создаю нового клиента и вызываю операцию сохранения, она сохранится в хранилище данных и сгенерирует идентификатор.

    Это правильно?И если мы вызываем save для уже постоянного объекта, не уверенного, что произойдет?

  • метод обновления: он используется для обновления уже постоянного объекта в хранилище данных. (В основном значение идентификатора будет некоторым ненулевым значением для этого).Подобно тому, как я загружаю нового клиента и вызываю операцию обновления после обновления некоторого значения поля, он обновит его в хранилище данных.

    Насколько я понимаю, это должно произойти с некоторым исключением, поскольку согласно обновлению API для отдельного объекта.Это правильно?Если да, что мы должны вызвать, чтобы обновить объект в том же сеансе (я имею в виду, если объект не отсоединен).Другой момент: что произойдет, если мы вызовем update для вновь созданного объекта?

  • saveOrUpdate: он будет вызывать любой из вышеперечисленных на основе проверок несохраненных значений (что он должен делать, основываясь на нулевом или ненулевом значении идентификатора, верно?), поэтому, если у нас есть постоянный объект customer, мы обновляем его фамилию и создаем новую учетную запись, тогда saveOrUpdate позаботится об этом.

    Правильно ли я понял?

  • Метод слияния: будет действовать как обновление, но здесь, если постоянный объект с тем же идентификатором уже находится в сеансе, онобновит значения отсоединенного объекта в постоянном объекте и сохранит его.

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

    Я тоже это получил?

Ответы [ 7 ]

30 голосов
/ 20 июня 2013

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

Обновление предназначено для вызова на отсоединенных объектах, то есть тех, которые сейчас находятся за пределами сеанса, в который они были загруженыПохоже, что объяснение @hvgotcodes неверно, поскольку обновление следует вызывать только в том случае, если в сеансе объект не .обновление может завершиться неудачно, если экземпляр объекта уже находится в сеансе.Слияние должно быть использовано в этом случае.Он объединяет изменения отдельного объекта с объектом в сеансе, если он существует.Если в сеансе нет объекта, он создаст новый.

Так часто вы вообще можете избежать вызова update / merge, но если вам в итоге придется вызывать один, слияние обрабатывает более широкий диапазон ситуаций.,Насколько я понимаю, единственная причина для использования обновления - это повышение производительности, если вы знаете, что оно не даст ошибок.

В этой теме также есть довольно хорошее резюме некоторых других методов гибернации..

Редактировать: я просто подумал, что должен сказать, что между слиянием и обновлением больше различий, чем я первоначально сказал.Обновление изменяет данную сущность, чтобы быть постоянной, тогда как слияние возвращает новую постоянную сущность.Для слияния вы должны выбросить старый объект.Другое отличие состоит в том, что слияние выполняет грязную проверку, выбирая из БД, прежде чем решить, записывать ли свои данные, тогда как обновление всегда сохраняет свои данные в БД, независимо от того, грязное оно или нет.

Возможно, есть и другие небольшие различия.Всегда полезно проверить поведение Hibernate, зарегистрировав сгенерированный SQL, потому что поведение не всегда соответствует документации, по крайней мере, по моему опыту.

11 голосов
/ 19 сентября 2011

Вы абсолютно правы во всех ваших оценках.Вы получите это.

На ваш первый вопрос, если я правильно помню, save специально делает вставку.Поэтому повторный вызов save приведет к появлению еще одной строки в базе данных.

По второму вопросу update обновляет объект в сеансе.Поэтому, если объект находится в сеансе, он обновится.Если объект не находится в сеансе, вы должны вызвать слияние.Я считаю, что вызов update для отдельного экземпляра приведет к исключению.

7 голосов
/ 05 декабря 2015

@ Налиба дала отличный ответ по методу Update ().

Жизненный цикл гибернации на следующем рисунке помогает лучше понять методы.

enter image description here

Пример: Давайте посмотрим merge() метод ситуации.

SessionFactory factory = cfg.buildSessionFactory();
Session session1 = factory.openSession();

Student student1 = null;
Object object1 = session1.get(Student.class, new Integer(101));
student1 = (Student)object1;
session1.close();

student1.setMarks(97);// -->object will be in some RAM location, not in the session1 cache

Session session2 = factory.openSession();
Student student2 = null;
Object object2 = session2.get(Student.class, new Integer(101));
student2 = (Student)object2;
Transaction tx=session2.beginTransaction();

session2.merge(student1);

Выше student1 находится в отсоединенном состоянии, изменил этот отсоединенный объект student1, теперь, если мы вызовем метод update(), то hibernate выдаст ошибку.

В этом session2 мы вызвали session2.merge(s1);, теперь в student2 объект student1 изменения будут объединены и сохранены в базе данных.

4 голосов
/ 20 октября 2013

update() - для отдельных объектов и для временных объектов.если вызвать постоянные объекты, он выдаст NonUniqueObjectException, и это будет исправлено merge().

4 голосов
/ 25 сентября 2013

session.update () - используется для сценария, когда вы загружаете объект Person1 из сеанса гибернации.Теперь он используется в приложении - может быть и на стороне клиента, был обновлен.Мы хотим сохранить это снова.Мы знаем, что в объекте Person в базе данных не было никаких изменений.Таким образом, мы можем просто использовать обновление.

session.merge () - в приведенном выше сценарии, если были внесены изменения в личные данные до сохранения измененного объекта Person1, мы должны использовать слияние.Это объединит изменения.

session.save () - Может использоваться для сохранения нового объекта.Возвращает серийный номер.

session.persist () - это то же самое, что save (), но это пустой метод и ничего не возвращает.

session.saveOrUpdate () - Этот метод будет работать как для новых, так и для старых объектов.Если объект новый, он будет работать как простое сохранение или если объект уже будет постоянным, он будет работать как обновление.

session.lock () - используется только для снятия блокировки с объекта или вы можете сказать, чтобы проверить версию объекта.Он не предназначен для обновления объекта.Его следует использовать для повторного присоединения объекта, только если вы уверены, что состояние объекта еще не изменилось в базе данных.В противном случае, это может отменить изменения.<Приглашение больше очков по этому. </p>

3 голосов
/ 29 июля 2014

Слияние следует за

Слияние имеет интеллект.Он имеет много предварительных проверок перед тем, как произойдет фактическое слияние (если требуется)

  1. , если объект временный, он просто запускает запрос INSERT, делает объект постоянным (присоединяется к сеансу)
  2. , еслиОбъект отсоединяется, запускает запрос на выборку, чтобы проверить, были ли данные изменены или нет, если модифицирован, запускает запрос UPDATE, в противном случае просто игнорируется задача слияния.

, где в качестве сеансаисключение, если объект временный.

если объект отсоединен, он просто запускает запрос UPDATE независимо от изменений данных в объекте.

session.merge дороже, чем update

0 голосов
/ 15 декабря 2016

Чтобы добиться максимальной производительности, вы должны применить различие между методами save () и saveOrUpdate в своем коде:

Метод save () возвращает идентификатор, сгенерированный базой данных.С другой стороны, saveOrUpdate () может делать INSERT или UPDATE в зависимости от того, существует объект в базе данных или нет.И saveOrUpdate сначала делает выбор, чтобы определить, нужно ли ему вставлять или обновлять.Поэтому вы должны использовать saveOrUpdate в случае запроса на обновление.

Другое ключевое отличие между методами save () и saveOrUpdate () состоит в том, что метод save () используется для перевода временного объекта в постоянное состояние, но saveOurUpdate () может сделатькак временный (новый объект), так и отдельный (существующий объект) объект в постоянном состоянии.Так что saveOrUpdate () часто используется для повторного присоединения отсоединенного объекта в Session.

Из сообщения Разница между save и saveOrUpdate в Hibernate

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...