Как только сеанс, используемый для сохранения, загрузки, получения или поиска объекта, был закрыт, объект становится отделенным.Это означает, что он больше не подключен к сеансу и работает как любой другой POJO.
Когда объект присоединяется и вы меняете одно из его свойств, Hibernate автоматически сохраняет изменения, внесенные в соответствующую строку вбаза данных (во время сброса / фиксации).
При отсоединении изменения, внесенные в объект, не сохраняются автоматически в базе данных.Чтобы сохранить изменения, вам нужно сделать это самостоятельно, вызвав session.update () или session.merge ().Оба метода делают более или менее одно и то же, но делают это по-разному.Я лично предпочитаю использовать слияние, которое менее опасно и приводит к меньшему количеству ошибок.
Читать http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached для более подробной информации
В вашем коде человек передан в качестве аргумента для редактированияМетод, вероятно, отстранен.Что вы делаете, так это получаете человека с тем же идентификатором, что и тот, который был передан из сеанса.existingPerson
прилагается.Затем вы копируете все свойства от отдельного лица к прикрепленному существующему человеку.И, наконец, вы сохраняете существующее лицо.
В этом коде есть 3 проблемы:
- сохранение не делает то, что вы думаете, оно делает.сохранить для вставки нового объекта лица.Ваш существующий человек уже существует и уже имеет идентификатор, поэтому необходимо использовать операцию обновления или слияния.
- Вам даже не нужно использовать обновление или слияние, поскольку, поскольку существующий_персонал присоединен к сеансу, сделанные вами изменения (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);
}