3

我有一个数据库表“viewmodule”,它本身有一个 FK(parent_id),以允许递归结构。

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

我的 Java 应用程序使用 JPA/Hibernate 来映射该表上的实体。我们已经修复了实体层级问题,这是通过使用表的“类型”列的@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 对象树,并从具有 hide=true 的子关系中删除 viewModules;

但是,由于所有对象仍处于 jpa/hibernate entityManager 的观察之下,因此从集合中删除的每个操作都直接作为数据库中的删除执行。所以我的过滤功能从数据库中删除了实体,这是一件坏事。

我尝试使用休眠会话中的“驱逐”方法在过滤之前分离实体,但这会导致 LazyInitialisationException。

所以,为了防止克隆我的所有对象,我的问题是如何解决这个问题?有没有办法以初始化所有集合的方式分离对象?或者是否有可以过滤集合的特殊 Kung-Fu Chuck-Norris JPA 注释?

提前致谢

4

2 回答 2

1

使用本机查询

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

这有效:过滤器列表包含在 jpa/hibernate 查询返回的实体中

于 2011-07-27T09:02:36.523 回答
0

创建一个新集合并仅添加具有hide=false. 您将无法将该集合与对象一起分发,因此您必须从单独的方法调用中返回它。例如:dao.getVisibleItems(module)

另一件事 - 如果您不需要它们,您可以删除 Cascade.DELETE(即列出除删除之外的所有级联)和孤儿删除。

于 2011-07-27T08:53:15.833 回答