分离对象如何在休眠状态下工作 [英] How does the detached object work in hibernate

查看:79
本文介绍了分离对象如何在休眠状态下工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



假设我有一个带有html文本字段的表单,并且有一个带有html文本字段的表单有保存按钮,它保存在数据库中的文本。



我有这个代码

  public void edit(Person person){
logger.debug(Editing existing person);

//从Hibernate检索会话
Session session = sessionFactory.getCurrentSession();

//通过id
检索现有人员Person existingPerson =(Person)session.get(Person.class,person.getId());

//将更新的值分配给此人
existingPerson.setFirstName(person.getFirstName());
existingPerson.setLastName(existingPerson.getLastName());
existingPerson.setMoney(existingPerson.getMoney());

//保存更新
session.save(existingPerson);
}

现在我可以保存任意数量的时间来保存数据。 p>

现在这是否意味着一旦我第一次保存,就会变得分离。
所以我需要做一些特别的事情,或者没关系。

我想知道在什么情况下我需要编程任何关于分离状态

解决方案

只要会话用于保存,加载,获取或查找实体已关闭,实体就会分离。这意味着它不再连接到一个会话,并且像任何其他POJO一样工作。



当一个实体被连接并且你改变了它的一个属性时,Hibernate会自动保存您对数据库中的相应行进行更改(在刷新/提交时)。

分离时,您对该对象所做的更改不会自动保存到数据库中。为了保存更改,您需要通过调用session.update()或session.merge()来自己完成更改。两种方法或多或少都有相同的作用,但做法不同。我个人更喜欢使用合并,这是不那么危险,并导致更少的错误。



阅读 http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached 获取更多详细信息

在您的代码中,作为参数传递给编辑方法的人可能已被分离。你正在做的是获取与会话中传递的ID相同的人员。因此附上 existingPerson 。然后,将所有属性从独立人员复制到所连接的existingPerson。最后,您保存了现有的人。



此代码有三个问题:


  1. 保存不会做你认为它做的事。保存用于插入新的人物对象。您的现有人已经存在并且已经有一个ID,因此要使用的操作是更新或合并。

  2. 您甚至不需要使用更新或合并,因为既然existingPerson被附加到会话中,所做的更改(setFirstName,setLastName等)将自动被持久化在冲洗时休眠。它是透明的。

  3. 您已经实现的算法与merge相同(除了级联等),它会自动为您执行所有操作。

因此应改为:

  public void edit(Person person){
logger.debug(Editing existing person,which is a detached object);

//从Hibernate检索会话
Session session = sessionFactory.getCurrentSession();

//通过id检索现有人,然后将所有从分离人员
//中的所有内容复制到附加人员,并返回附加的一个
Person existingPerson =(Person)session.merge人);
}


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.

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.

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).

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(). 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.

Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-detached for more details

In your code, the person passed as argument to the edit method is probably detached. What you're doing is getting the person with the same ID as the one passed from the session. existingPerson is thus attached. Then you copy all the properties from the detached person to the attached existingPerson. And finally, you save the existingPerson.

There are 3 problems with this code :

  1. save doesn't do what you think it does. save is for inserting a new person object. Your existing person already exists and already has an ID, so the operation to use is update or merge.
  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. 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);
}

这篇关于分离对象如何在休眠状态下工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆