我有一个数据库表“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 注释?
提前致谢