Как отдельный объект работает в спящем режиме - PullRequest
10 голосов
/ 10 марта 2011

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

Предположим, у меня есть одна форма с текстовыми полями html, и есть кнопка сохранения, которая сохраняет текст в базе данных.

У меня есть этот код

 public void edit(Person person) {
  logger.debug("Editing existing person");

  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();

  // Retrieve existing person via id
  Person existingPerson = (Person) session.get(Person.class, person.getId());

  // Assign updated values to this person
  existingPerson.setFirstName(person.getFirstName());
  existingPerson.setLastName(existingPerson.getLastName());
  existingPerson.setMoney(existingPerson.getMoney());

  // Save updates
  session.save(existingPerson);
 }

Теперь я могу нажать «Сохранить» сколько угодно раз, чтобы сохранить данные.

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

Я хочу знать, при каких условиях мне нужно программировать что-либо об отключенном состоянии

1 Ответ

22 голосов
/ 10 марта 2011

Как только сеанс, используемый для сохранения, загрузки, получения или поиска объекта, был закрыт, объект становится отделенным.Это означает, что он больше не подключен к сеансу и работает как любой другой POJO.

Когда объект присоединяется и вы меняете одно из его свойств, Hibernate автоматически сохраняет изменения, внесенные в соответствующую строку вбаза данных (во время сброса / фиксации).

При отсоединении изменения, внесенные в объект, не сохраняются автоматически в базе данных.Чтобы сохранить изменения, вам нужно сделать это самостоятельно, вызвав session.update () или session.merge ().Оба метода делают более или менее одно и то же, но делают это по-разному.Я лично предпочитаю использовать слияние, которое менее опасно и приводит к меньшему количеству ошибок.

Читать http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached для более подробной информации

В вашем коде человек передан в качестве аргумента для редактированияМетод, вероятно, отстранен.Что вы делаете, так это получаете человека с тем же идентификатором, что и тот, который был передан из сеанса.existingPerson прилагается.Затем вы копируете все свойства от отдельного лица к прикрепленному существующему человеку.И, наконец, вы сохраняете существующее лицо.

В этом коде есть 3 проблемы:

  1. сохранение не делает то, что вы думаете, оно делает.сохранить для вставки нового объекта лица.Ваш существующий человек уже существует и уже имеет идентификатор, поэтому необходимо использовать операцию обновления или слияния.
  2. Вам даже не нужно использовать обновление или слияние, поскольку, поскольку существующий_персонал присоединен к сеансу, сделанные вами изменения (setFirstName, setLastName и т. Д.) Будут автоматически сохраняться Hibernate во время сброса.Он прозрачен.
  3. Реализованный вами алгоритм такой же (за исключением каскадов и т. Д.), Что и алгоритм слияния, который делает все это автоматически для вас.

Таким образом, его следует изменить на:

public void edit(Person person) {
  logger.debug("Editing existing person, which is a detached object");

  // Retrieve session from Hibernate
  Session session = sessionFactory.getCurrentSession();

  // Retrieve existing person via id, then copy everything from detached person 
  // to attached one, and return attached one
  Person existingPerson = (Person) session.merge(person);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...