【问题标题】:JPA Specification: filter child entitiesJPA 规范:过滤子实体
【发布时间】:2015-01-21 12:01:37
【问题描述】:

我成功地为我的应用程序实体实现了软删除(又名删除标志)。但是,我还有一个问题。 我用 findAll 和 count 方法编写了一个自定义 JPARepository 过滤掉已删除的方法。我按照规范执行此操作:

softDeleteSpecification = new Specification<T>() {
        @Override
        public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.or(cb.isNull(root.get(DELETED_FIELD_NAME)), cb.equal(root.<T>get(DELETED_FIELD_NAME), false));
        }
    };

例如,如果实体具有同样被软删除的实体的 OneToMany 子列表,则不会过滤此列表,因为查询不是由其存储库运行的。

我的问题:我可以修改上面的规范,以便过滤掉软删除的孩子吗? 另一种方法是使用反射过滤子项(在查询之后手动),但这不会是高效的。

【问题讨论】:

    标签: java hibernate jpa soft-delete


    【解决方案1】:

    借助 Hibernate,您可以在实体上使用 @Whereannotation

    @Entity
    @Where(clause = "deleted = 0")
    public class MyEntity {
    ...
    

    也就是说,请查看@SQLDelete,了解软删除实施的替代方案。

    【讨论】:

    • 我们已经尝试过了。额外的 where 子句被添加到对实体本身执行的查询中,对具有急切获取的父项执行的查询,而不是具有延迟获取的查询。附带说明:我们试图避免特定于 Hybernate 的命令,因为我们不想要任何直接依赖。这就是我构建自定义软删除解决方案而不是使用 where 子句的原因。不过 where 子句是个好主意。
    【解决方案2】:

    我得到了这个工作。如果每个产品都有一个子实体类别,即类别是产品的子实体,下面的代码对我有用

    public static Specification<Product> whereCategoryNameEquals(@NonNull String categoryName)  {
        return (Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) 
            -> cb.equal(root.get(Product_.CATEGORY).get(Category_.CATEGORY_NAME),categoryName);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 2021-12-06
      • 2013-03-23
      • 2023-01-31
      相关资源
      最近更新 更多