简体   繁体   English

分离对象如何在休眠中工作

[英]How does the detached object work in hibernate

I know that object is in detached state when we already hit save and we have to re-attach it. 我知道当我们已经点击保存并且我们必须重新附加它时,该对象处于分离状态。

Suppose i have one form with html text fields and there is save button which saves the text in database. 假设我有一个带有html文本字段的表单,并且有一个保存按钮,用于将文本保存在数据库中。

i have thise code 我有这个代码

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

Now i can hit save any number of time to save the data. 现在我可以节省任何时间来保存数据。

Now does that mean that once i hit save first time , it becomes detached. 现在这是否意味着一旦我第一次点击保存,它就会变得分离。 So do i need to do something special for that or it does not matter. 所以我需要做一些特别的事情,或者无关紧要。

I want to know under what condition i need to program anything about detached state 我想知道在什么条件下我需要编写关于分离状态的任何东西

As soon as the session used to save, load, get or find an entity has been closed, the entity becomes detached. 一旦用于保存,加载,获取或查找实体的会话已关闭,该实体就会分离。 This means that it's not connected anymore to a session, and works like any other POJO. 这意味着它不再连接到会话,并且像任何其他POJO一样工作。

When an entity is attached and you change one of its properties, Hibernate automatically saves the changes you made to the corresponding row in the database (at flush/commit time). 当附加实体并更改其中一个属性时,Hibernate会自动将您所做的更改保存到数据库中的相应行(在刷新/提交时)。

When it's detached, the changes you made to the object are not saved automatically to the database. 分离时,对对象所做的更改不会自动保存到数据库中。 In order to save the changes, you need to do it yourself, by calling the session.update() or session.merge(). 为了保存更改,您需要通过调用session.update()或session.merge()来自行完成。 Both methods do more or less the same thing, but do it differently. 两种方法或多或少都做同样的事情,但做的却不同。 I personnally prefer using merge, which is less dangerous and leads to less bugs. 我个人更喜欢使用merge,这样不那么危险并且导致更少的bug。

Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached for more details 阅读http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached了解更多详情

In your code, the person passed as argument to the edit method is probably detached. 在您的代码中,作为参数传递给edit方法的人可能已经分离。 What you're doing is getting the person with the same ID as the one passed from the session. 你正在做的是获得与会话中传递的ID相同的人。 existingPerson is thus attached. 因此附加了existingPerson Then you copy all the properties from the detached person to the attached existingPerson. 然后将所有属性从分离的人复制到附加的existingPerson。 And finally, you save the existingPerson. 最后,您保存现有的Peron。

There are 3 problems with this code : 这段代码有3个问题:

  1. save doesn't do what you think it does. 保存不会做你认为它做的事情。 save is for inserting a new person object. save用于插入新的person对象。 Your existing person already exists and already has an ID, so the operation to use is update or merge. 您现有的人已经存在且已有ID,因此要使用的操作是更新或合并。
  2. You don't even need to use update or merge, because since existingPerson is attached to the session, the changes you make (setFirstName, setLastName, etc.) will automatically be made persistent by Hibernate at flush time. 您甚至不需要使用更新或合并,因为现在,因为existingPerson附加到会话,所以您在更新时会自动使更改(setFirstName,setLastName等)由Hibernate持久化。 It's transparent. 这是透明的。
  3. The algorithm you have implemented is the same one (except for cascades, etc.) as the one used by merge, which does all this automatically for you. 您实现的算法与合并使用的算法相同(除了级联等),它会自动为您完成所有这些操作。

It should thus be changed to : 因此应改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM