java - 分离的对象如何在 hibernate 中工作

标签 java hibernate spring

当我们已经点击保存时,我知道该对象处于分离状态,我们必须重新附加它。

假设我有一个带有 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个问题:

  1. save 不会像您认为的那样做。 save 用于插入一个新的 person 对象。您现有的人已经存在并且已经有一个 ID,所以要使用的操作是更新或合并。
  2. 您甚至不需要使用更新或合并,因为由于 existingPerson 已附加到 session ,您所做的更改(setFirstName、setLastName 等)将在刷新时由 Hibernate 自动持久化。它是透明的。
  3. 您实现的算法与 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/

相关文章:

Spring、Infinispan 和 JBoss 7 集成

java - 实现删除链表最后一个节点的方法

java - 如何合并 Spark 数据集中的行以合并字符串列

java - 我们如何知道哪个登录用户正在使用java中的表单?

java - 使用 JPA 查询可为空的 @OneToOne 关系

java - Spring引用JDBC缺陷?

java - 注入(inject)构造函数时出错,java.lang.NoClassDefFoundError : com/thoughtworks/xstream/io/HierarchicalStreamDriver in Spring MVC

java - 如何从kotlin接口(interface)访问java接口(interface)中定义的常量

java - 如何在Java中实现函数参数的元组解包?

java - 对组合键的一部分进行条件查询