Как работает отдельный объект в спящем режиме

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

Предположим, что у меня есть одна форма с текстовыми полями 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

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

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

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

Подробнее читайте http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached

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

С этим кодом возникают 3 проблемы:

  • save не делает то, что вы думаете. save - для вставки нового объекта person. Ваш существующий человек уже существует и уже имеет идентификатор, поэтому операция для использования - это обновление или слияние.
  • Вам даже не нужно использовать обновление или слияние, потому что, поскольку existingPerson подключен к сеансу, сделанные вами изменения (setFirstName, setLastName и т.д.) автоматически будут выполняться с помощью Hibernate во время очистки. Это прозрачно.
  • Алгоритм, который вы реализовали, является тем же (за исключением каскадов и т.д.), как тот, который используется слиянием, что делает все это автоматически для вас.

Поэтому он должен быть изменен на:

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);
}