You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate 6.4如何绕过@SoftDelete限制查询所有记录?

解决Hibernate @SoftDelete下查询所有记录(含已删除)的方案

当你用Hibernate的@SoftDelete注解后,框架会自动给所有查询追加deleted = false的过滤条件,要绕过这个限制,有以下几种可行方法:

1. 自定义可开关的Filter覆盖默认软删除规则

Hibernate的软删除是通过内置Filter实现的,你可以在实体类上定义一个自定义Filter,手动控制是否包含已删除记录:

@Entity
@SoftDelete(columnName = "deleted")
@FilterDef(name = "includeDeleted", parameters = @ParamDef(name = "includeDeleted", type = Boolean.class))
@Filter(
    name = "includeDeleted",
    condition = "deleted = :includeDeleted OR :includeDeleted = TRUE"
)
public class YourEntity {
    // 实体字段、getter/setter...
}

查询时启用这个Filter并传入true参数:

Session session = entityManager.unwrap(Session.class);
// 启用Filter,设置包含已删除记录
session.enableFilter("includeDeleted").setParameter("includeDeleted", true);
// 执行查询,此时会返回所有记录(含已删除)
List<YourEntity> allRecords = session.createQuery("FROM YourEntity", YourEntity.class).list();
// 可选:查询完成后关闭Filter,避免影响后续默认查询
session.disableFilter("includeDeleted");

2. 用原生SQL直接查询(完全绕过Hibernate过滤)

如果之前用原生SQL还是被加条件,大概率是因为你关联了实体类导致Hibernate介入。试试直接返回原生结果集,手动转换:

String sql = "SELECT id, name, deleted FROM your_entity";
List<Object[]> rawResults = entityManager.createNativeQuery(sql).getResultList();
// 手动映射为实体对象
List<YourEntity> allRecords = rawResults.stream()
    .map(row -> {
        YourEntity entity = new YourEntity();
        entity.setId((Long) row[0]);
        entity.setName((String) row[1]);
        entity.setDeleted((Boolean) row[2]);
        return entity;
    })
    .collect(Collectors.toList());

3. 禁用Hibernate的软删除Filter(依赖Hibernate API)

通过EntityManager获取Hibernate原生Query对象,直接关闭软删除过滤:

javax.persistence.Query jpaQuery = entityManager.createQuery("SELECT e FROM YourEntity e");
org.hibernate.query.Query hibernateQuery = jpaQuery.unwrap(org.hibernate.query.Query.class);
// 关闭软删除的内置Filter
hibernateQuery.setHibernateFilter("softDelete", false);
List<YourEntity> allRecords = hibernateQuery.getResultList();

注意:这个方法直接依赖Hibernate私有API,项目如果切换JPA实现会失效,适合纯Hibernate项目。

4. 创建无软删除的视图实体(适合频繁查询场景)

如果业务中经常需要查全量数据,可以给原表创建一个数据库视图,然后创建对应视图的实体类(不加@SoftDelete):

  • 先建数据库视图:
CREATE VIEW your_entity_full AS SELECT * FROM your_entity;
  • 创建视图对应的实体:
@Entity
@Table(name = "your_entity_full")
public class YourEntityFull {
    @Id
    private Long id;
    private String name;
    private Boolean deleted;
    // getter/setter...
}
  • 查询这个实体就能直接获取所有记录:
List<YourEntityFull> allRecords = entityManager.createQuery("FROM YourEntityFull", YourEntityFull.class).getResultList();

内容的提问来源于stack exchange,提问作者Nipuna Perera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:59:55