“绕过”JPA 查询实体上的@SQLRestriction

问题描述 投票:0回答:1

背景

我正在 JPA/Hibernate 应用程序中实现软删除和硬删除功能。给定一个定义了SQLRestriction的实体,以限制 JPA 中的每个查询返回非软删除数据:

@Entity
@SQLRestriction("deleted = false")
public class Product extends Auditables {

    @Id
    @SnowFlakeIdValue(name = "product_id")
    @Column(name = "product_id", columnDefinition = "BIGINT", updatable = false, nullable = false)
    @Column(name = "deleted", nullable = false)
    private boolean deleted = false;

    @Version
    private Long version;

    @OneToMany(mappedBy = "product", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    private Set<Variant> variants = new HashSet<>();

    @OneToMany(mappedBy = "product", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    private Set<ProductImage> images = new HashSet<>();
}

请注意,@SQLRestrictions 始终适用且无法禁用。它们也不可能被参数化。因此,它们的灵活性远不如过滤器。

这是否意味着我们无法选择满足限制条件的数据?我需要在特定情况下查询和管理未删除和软删除的记录(例如,硬删除),但始终应用 @SQLRestriction 并且无法根据 Hibernate 文档禁用或参数化。

附加信息

至于软删除的工作原理,我没有使用@SoftDelete,而是更新了相应请求产品的

deleted
字段。

尝试过的方法

由于我希望能够软删除和硬删除,我在仍然使用@SQLRestriction的同时尝试了各种方法,其中之一是:

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
    @Query("SELECT p FROM Product p")
    @SQLRestriction("")
    List<Product> findAllUnfiltered();

    @Modifying @Transactional
    @Query("DELETE FROM Product p WHERE p.productId = :productId AND p.deleted IN (true, false)")
    void deleteProductPermanently(@Param("productId") Long id);

    @Modifying @Transactional
    @Query("DELETE FROM Product p WHERE p.deleted IN (true, false)")
    void deleteAllProductsPermanently();
}

这些尝试都没有成功绕过@SQLRestriction。

问题与疑问

有没有办法在需要时绕过@SQLRestriction,同时保持对常规查询的自动过滤?如果没有,推荐的方法是什么?

  • 切换到休眠过滤器?
  • 直接使用EntityManager?
  • 编写原生 SQL 查询?
  • 还有其他选择吗?

环境

Spring Boot框架:3.3.4 Hibernate(.orm,核心):6.5.3 Final

java database spring-boot hibernate spring-data-jpa
1个回答
0
投票

显然使用 SQLRestriction 是不可能的。

对于您的情况

@Filter
@FilterDef
似乎是您可以禁用实体管理器的方法。

有一篇文章描述了确切的用例。出于管理目的等目的访问软删除的数据。

https://www.baeldung.com/spring-jpa-soft-delete

© www.soinside.com 2019 - 2024. All rights reserved.