2012-10-27 47 views
6

我使用Hibernate 4.1.7和尝试更新的对象,但世界上没有文档,它应该怎么做。目前,我这样做:休眠更新的EntityManager

Person person = personDao.getPersonById(1); 
    person.setAge(23); 
    person.setLastname("McName"); 
    person = personDao.update(person); 

在PersonDao的更新的样子:

public Person update(Person person) { 
     return entityManager.merge(person); 
    } 

在PersonDao的getPersonById是:

public Person getPersonById(int id) { 
     personQuery = entityManager.createNamedQuery("Person.findPerson", Person.class); 
     personQuery.setParameter("id", id); 
     return personQuery.getSingleResult(); 
    } 

我也有Person类中定义命名查询,并在这里:

@NamedQuery(name="Person.findPerson", query="SELECT p FROM Person p WHERE p.id = :id") 

通过使用我的Person不会被更新,我应该如何使用hibernate实现更新?

+0

上面的代码行,不同的是,如果一切都在单个事务中运行调用'personDao.update()'是完全没有必要的:一个实体的状态被自动地进行持久通过JPA /休眠在交易结束。 getPersonById方法也可以简化为'em.find(Person.class,id)',这会更简单,更高效,因为如果实体已经加载,它不会执行任何查询。 –

+0

附录:这在文档中有明确的解释。见http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html_single/#d5e772 –

回答

4

两种情况可能会弹出你。

您可能需要改变对象的属性,而只有财产。

如果这是你要使用的方法的情况下:查找,修改,冲洗,提交。

em.find(Person.class, person.getId()) 
person.setStatus("ACTIVE"); 
em.commit();//implicitly flushes if flush mode is COMMIT or AUTO. 

您可能想要使用对象属性来更新该项目。

如果这是你想要使用的方法:合并,可选修改,刷新,提交。

em.merge(person); 
//modify person if you wish. 
em.commit();//implicitly flushes if flush mode is COMMIT or AUTO. 
+0

找到我的解决方案,最后我用 entityManager.getTrasaction()。begin(); person = entityManager.find(Person.class,id); entityManager.merge(person); //修改人员数据 entityManager.getTransaction()。commit(); – Timo

+0

很高兴你找到了解决方案。如果find(Person.class,id)期间使用的id是执行merge(person)时使用的person.id,则合并可能不是必需的。一旦你找到了,你的实体就被管理了,你可以修改和提交你的修改。 – dseibert

0

我不知道你问究竟是什么,但在你的方法,Person.getPersonById(int id),你可以用下面的简化代码:

return entityManager.find(Person.class, id); 
1

休眠以及其他JPA实现自动管理实体的状态并且如果修改被包含在事务中,则将其保存到数据库。您无需明确呼叫mergeupdate方法。

如果您正在使用本地资源的事务(不JTA事务管理器管理)尝试这样的事:

EntityTransaction tx = entityManager.getTransaction(); 
tx.begin(); 
Person person = personDao.getPersonById(1); 
person.setAge(23); 
person.setLastname("McName"); 
tx.commit(); 

和所有的修改都将自动保存在数据库中。

如果您正在使用JTA,那么你必须通过使用Spring AOP @Transactional标注在一些其他的方式来标记事务边界,例如。

+0

我使用hsqldb(资源本地),并通过使用此代码我得到异常:org.hibernate。 PersistentObjectException:传递给persist的分离实体:com.application.model.Person – Timo

+0

可能您正在使用两个不同的EntityManager实例。 – Jarek