【问题标题】:Filter JPA Entities without removing them from database过滤 JPA 实体而不将它们从数据库中删除
【发布时间】:2011-10-14 01:47:33
【问题描述】:

我有一个数据库表“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 的观察下,从集合中删除的每个操作都直接作为数据库中的删除执行。所以我的过滤函数从数据库中删除了实体,这是一件坏事。

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

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

提前致谢

【问题讨论】:

    标签: java hibernate jpa lazy-initialization hibernate-entitymanager


    【解决方案1】:

    使用原生查询

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

    这可行:Filter list contained in entity returned by jpa/hibernate query

    【讨论】:

    • 这取决于您的应用程序约束,如果您的应用程序可以允许 ViewModule 具有“隐藏”父级,那么上述方法将不起作用。但是,如果在您的应用程序的某处强制执行约束,则上述查询应该可以工作
    • 我认为这应该是解决方案stackoverflow.com/questions/3300280/…
    • 是的。我以错误的方式使用了过滤器。我在调用 query.getResultList() 后直接禁用了过滤器。这具有禁用子级延迟初始化的过滤器的效果。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多