2013-10-26 110 views
8

我試圖插入一個人POJO到MySQL數據庫使用Hibernate EntityManager的persist方法分離的實體,休眠例外:通過堅持

entityManagerTransactionService.getEntityManager().persist(TemplateObject); 

,並得到這個例外,

javax.persistence.PersistenceException: 
org.hibernate.PersistentObjectException: detached entity passed to 
persist: com.esupu.base.model.pojo.common.TitleType at 
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387).... 

有更..

Caused by: org.hibernate.PersistentObjectException: detached entity 
passed to persist: com.esupu.base.model.pojo.common.TitleType at 
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141) 
    at 
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:843) 

我Person.java類,

@Entity 
public class Person extends TemplateObject { 

    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH }) 
     private TitleType titleType; 
     private String middle; 
     private String last; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Address address; 
     private Date birthdate; 
     private String email; 
     private String telephone; 
     private String fax; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Location location; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Country country; 

,然後POJO的吸氣setter方法..

扔TitleType類錯誤是「公共靜態最後的」標題類型定義提供商,

@Entity 
public class TitleType extends TemplateObject { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 3104954552111621034L; 

    private TitleType(int id, String name) { 
     setId(id); 
     setName(name); 
    } 

    public static final TitleType MR = new TitleType(1, "Mr"); 
    public static final TitleType MISS = new TitleType(2, "Miss"); 
    public static final TitleType MRS = new TitleType(3, "Mrs"); 
    public static final TitleType MS = new TitleType(4, "Ms"); 
    public static final TitleType DOCTOR = new TitleType(5, "Doctor"); 
    public static final TitleType PROFESSOR = new TitleType(6, "Professor"); 
    public static final TitleType SIR = new TitleType(7, "Sir"); 
    public static final TitleType MADAM = new TitleType(8, "Madam"); 

} 

我設置標題類型類的人,

person.setTitleType(TitleType.MR); 

是不可能將公共靜態最終類型定義類傳遞給Hibernate?或者有什麼我做錯了?

在此先感謝

+0

我們展示的代碼來持久化對象。看起來你試圖堅持一個分離的對象 – Shamse

回答

15

你想堅持的對象包括TitleType,不應該有ID值。否則,Hibernate將檢查該對象是否在會話上下文中持久或分離。如果您不想保留這樣的對象的某些字段,則可以使用@Transient註釋來在持久化實體時從字段映射中排除這些字段。這對硬編碼DAO或實體中的ID是不好的,因爲這些值可能由某個生成器生成,但是如果使用此常量手動更新數據庫,則至少可以在代碼中將這些ID定義爲常量,並根據ID從會話中加載對象在初始化瞬態或持久實例之前。

11

而不是做這個的:public static final TitleType MR = new TitleType(1, "Mr");

你應該使用EntityManager來獲取該對象。其他人會注意到,Hibernate會注意到這個對象(id爲1)已經被存儲,但是因爲你沒有加載它,所以實體管理器沒有在它自己的集合中 - >這是一個分離的實體。

所以,你應該做的:

TitleType MR = em.find(TitleType.class, 1); 
Person p = new Person(...); 
p.setTitleType(MR); 

em.merge(p); 
+0

我測試並發現你的答案正常工作也是正確的,但我選擇從TitleType DAO刪除id作爲nikpon建議,所以我不得不選擇他的答案作爲接受的,許多感謝您對雙方的幫助:) –

+0

這是一種骯髒的方法,因爲它將控制器級代碼與持久層代碼混合在一起。 – CodeMed

+2

@CodeMed不,它不是。這個例子很簡短,但是這是一條路。如果你想添加一個新的'user'到一個'group',你還需要*加載*現有的組,添加新的用戶,最後刷新你對數據庫的修改,而不必觸摸現有的組。 – dognose