2012-10-27 93 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