3

我有一個數據庫表「viewmodule」與FK本身(parent_id)允許遞歸結構。過濾JPA實體,而不從數據庫中刪除它們

CREATE TABLE viewmodule (
id, 
type, 
parent_id, 
hide); 

我的Java應用程序使用JPA/Hibernate映射該表上的實體。我們有固定的實體hirachy,它是通過使用表的「type」列的@ Discriminator註解來解決的。

public class ViewModule implements Serializable { 
    private long id; 
    private String type; 
    private ViewModule parent; 
    private Boolean hide; 

    @OneToMany(targetEntity = ViewModule.class, cascade = javax.persistence.CascadeType.ALL, mappedBy = "parent") 
    @Cascade({ org.hibernate.annotations.CascadeType.ALL, 
      org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
    private Set<ViewModules> children; 
(...) 
} 

我現在的任務就是裝載從這個表中的所有元素(深),但離開了,因爲他們場「隱藏」設置爲true的人。 它是一個明顯簡單的過濾機制。我的第一種方法是使用Hibernate Filter註釋,它在第一層(parent_id = null的所有視圖模塊)上運行良好。但過濾器不適用於「兒童」關係。 (在我的現實生活模型中,我有不同類型的ViewModules的繼承結構)

因此,我寫了一個遞歸遍歷viewModule對象樹並從children關係中刪除viewModules的小函數隱藏= TRUE;

但是,由於所有對象仍在觀察jpa/hibernate entityManager,因此每次從集合中刪除都將直接作爲數據庫中的刪除操作執行。所以我的過濾函數從數據庫中刪除實體,這是一件壞事。

我試圖從hibernate會話中使用「evict」方法在過濾之前分離實體,但這會導致LazyInitialisationException。

那麼,爲了防止克隆我所有的對象,我的問題是如何解決這個問題?有沒有辦法以所有集合被初始化的方式分離對象?還是有一個特殊的功夫查克 - 諾里斯JPA註釋可以過濾收藏?

在此先感謝

回答

1

使用本地查詢

em.createNativeQuery("select * from viewmodule where hide = false", ViewModule.class).getResultList(); 

這工作:Filter list contained in entity returned by jpa/hibernate query

+0

這是否會解決濾波的依賴呢? – martin

+0

,這取決於你的應用程序約束,如果你的應用程序可以允許一個ViewModule有一個「隱藏」的父項,那麼上述將不起作用。但是如果約束在您的應用程序的某處執行,那麼上述查詢應該可以工作 – Dapeng

+1

我認爲這應該是解決方案http://stackoverflow.com/questions/3300280/filter-list-contained-in-entity-returned-by -jpa-hibernate-query – Dapeng

0

創建一個新的收集和只添加有hide=false的元素。您將無法將該集合與對象一起分發,因此您必須從單獨的方法調用中將其返回。例如:dao.getVisibleItems(module)

另一件事 - 你可以刪除Cascade.DELETE(即列出除刪除以外的所有級聯)和孤兒刪除,如果你不需要它們。