我正在 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,同时保持对常规查询的自动过滤?如果没有,推荐的方法是什么?
Spring Boot框架:3.3.4 Hibernate(.orm,核心):6.5.3 Final
显然使用 SQLRestriction 是不可能的。
对于您的情况
@Filter
和@FilterDef
似乎是您可以禁用实体管理器的方法。
有一篇文章描述了确切的用例。出于管理目的等目的访问软删除的数据。