当我们已经点击保存时,我知道该对象处于分离状态,我们必须重新附加它。
假设我有一个带有 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);
}
现在我可以点击保存任意次数来保存数据。
现在这是否意味着一旦我第一次点击保存,它就会分离。 所以我需要为此做一些特别的事情还是没关系。
我想知道在什么情况下我需要编写关于分离状态的任何东西
最佳答案
一旦用于保存、加载、获取或查找实体的 session 关闭,实体就会分离。这意味着它不再连接到 session ,并且像任何其他 POJO 一样工作。
当一个实体被附加并且您更改其属性之一时,Hibernate 会自动保存您对数据库中相应行所做的更改(在刷新/提交时)。
分离后,您对对象所做的更改不会自动保存到数据库中。为了保存更改,您需要自己通过调用 session.update() 或 session.merge() 来完成。这两种方法或多或少都做同样的事情,但做的不同。我个人更喜欢使用合并,它的危险性较小,并且会导致较少的错误。
阅读 http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached了解更多
在您的代码中,作为参数传递给编辑方法的人可能是分离的。你正在做的是让那个人与从 session 中传递的那个人具有相同的 ID。 existingPerson
因此附加。然后将分离人员的所有属性复制到附加的现有人员。最后,保存现有的Person。
这段代码有3个问题:
- save 不会像您认为的那样做。 save 用于插入一个新的 person 对象。您现有的人已经存在并且已经有一个 ID,所以要使用的操作是更新或合并。
- 您甚至不需要使用更新或合并,因为由于 existingPerson 已附加到 session ,您所做的更改(setFirstName、setLastName 等)将在刷新时由 Hibernate 自动持久化。它是透明的。
- 您实现的算法与 merge 使用的算法相同(级联等除外),merge 会自动为您完成这一切。
因此应该改为:
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);
}
关于java - 分离的对象如何在 hibernate 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5260297/