2011-01-20 37 views
4

我有以下與@OneToOne關係的實體:無法刪除實體是@OneToOne關係的目標

@Entity 
public static class EntityChild extends BaseEntity { 
    //Id from superclass 
} 

@Entity 
public static class EntityParent extends BaseEntity { 

    //Id from superclass 

    @OneToOne(cascade = ALL) 
    private EntityChild child; 

    //child getter/setter 
} 

現在下面的測試不及格:

EntityParent parent = new EntityParent(); 
em.persist(parent); 
em.flush(); 

EntityChild child = new EntityChild(); 
parent.setChild(child); 
em.persist(parent); 
em.flush(); 

em.remove(parent.getChild()); 
em.flush(); 

它拋出異常,在最後行,用flush()。例外是javax.persistence.EntityNotFoundException: deleted entity passed to persist: [my.package.EntityChild#<null>]

爲什麼我不能刪除此實體?

回答

4

您需要先刪除父母和孩子之間的關係,否則Hibernate試圖再次堅持孩子由於cascade = ALL

EntityChild c = parent.getChild(); 
parent.setChild(null); 
em.remove(c); 
em.flush(); 

更新:

下面是摘錄從JPA specification相關到這種行爲。拋出異常由於間[1]和[2] flush()(雖然我不能找到它的指定位置)期間衝突:

沖洗操作的語義,應用到實體X如如下:

  • 如果X是一個託管實體,它會同步到數據庫。

    • 對於由從X的關係中引用的所有實體Y,如果Y的關係一直 與cascade元件值cascade=PERSISTcascade=ALL註釋,persist操作被施加到Y

    • 對於從X的關係引用的任何實體Y,其中與Y的關係具有 未註明cascade元素值cascade=PERSISTcascade= ALL

      • 如果Y是新的或刪除,一個IllegalStateException將由刷新操作(與標記爲回滾事務)或 提交會失敗交易拋出 。

      • 如果Y被分離,語義取決於關係的所有權。 如果X擁有該關係,則關係的任何更改將與數據庫同步 ;否則,如果Y擁有關係,則行爲 未定義。

  • 如果X是一個移除的實體,它從數據庫中刪除。沒有級聯選項是相關的。< --------------- [1]


的語義堅持 操作中,施加到一個實體X是 如下:

  • 如果X是一個新的實體,它 變成管理。實體X將在 事務提交或 刷新操作的結果 或之前輸入到數據庫中。

  • 如果X是一個 先前存在的被管實體,則它被 忽略的持久操作。 然而,持續操作是 級聯到由X, 引用的實體,如果從X到這些 其他實體的關係被註釋與 cascade=PERSISTcascade=ALL 註釋元素值或與該等效XML描述 元素指定 。

  • 如果X是一個被刪除的實體,它將被管理。 < --------------- [2]

  • 如果X是一個 分離對象,所述 EntityExistsException可能拋出 當persist操作被調用時, 或EntityExistsException或 另一個PersistenceException可能在沖洗或提交時拋出 。

  • 對於 通過從X一 關係引用,如果 關係爲Y已經被註釋 與級聯元件值的所有實體ý cascade=PERSISTcascade=ALL,所述 persist操作被施加到Y

+0

它的工作原理,謝謝@axtavt!不過,我想完全理解它。當我移除孩子然後沖洗時,他們是否看到與這個孩子的關係,發現父母有關係,併合並父母?然後很明顯,在父母中有孩子,所以它試圖堅持下去。是對的嗎? – amorfis 2011-01-20 14:52:19