2011-11-12 64 views
5

我想知道哪個實現remove方法的更好:刪除操作的JPA和DAO實現

public void remove(T t) { 
    entityManager.remove(entityManager.merge(t)); 
} 

public void remove(PK pk) { 
    entityManager.remove(entityManager.getReference(entityType, pk)); 
} 

我讀了很多篇關於這一點,在他們幾乎每一個它類似於第一種方法,這在我看來很不必要,因爲它可以在不需要從數據庫中檢索整個實體(如果它不存在於持久性上下文中)並且然後將其刪除的情況下完成。有什麼我失蹤了,第一種方法真的更好嗎?

+1

你爲什麼不叫'entityManager.remove(T)'? – stacker

+0

@stacker:我想要這個方法去除管理和分離的實體。 – VaclavDedik

回答

1

你可以檢查的實體是否是通過調用

boolean isManaged = entityManager.contains(t); 

如果真管理簡單地調用

entityManager.remove(t); 

否則你的第二個方法似乎更好,因爲合併可能會導致更多的DB活動由於預先加載(如果配置)。在getReference上的javadoc說:「獲取一個實例,它的狀態可能會被延遲取出,如果請求的實例不存在於數據庫中,當第一次訪問實例狀態時會拋出EntityNotFoundException(持久化提供程序運行時允許在getReference時拋出EntityNotFoundException (java.lang.Class,java.lang.Object)被調用。)應用程序不應該期望實例狀態在分離時可用,除非應用程序在實體管理器打開時訪問它。

總之實體必須therfore管理,我建議:

em.remove(em.contains(r) ? r : em.merge(r)); 
+0

這個解決方案看起來不錯,但是,如果執行沿着「DELETE FROM Entity e WHERE e.id =:id」行的JPQL/HQL查詢將比調用快合併,然後刪除,當實體不包含在經理?構建一個查詢outweight的開銷是否不需要獲取實體? – esaj

+1

對我來說似乎沒有必要,如果實體存在於持久化上下文中,調用em.merge(r)將返回對託管實體的引用。這不是這個問題的關鍵。令我困擾的是,當實體不存在於持久化上下文中時,因爲合併方法必須從數據庫中檢索實體,在這種情況下,在我看來,這是不必要的,因爲我只需要從數據庫中刪除一行。 – VaclavDedik