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

Hibernate @OneToMany关联如何自动过滤标记为已删除的子实体

Hibernate提供了多种原生机制满足你的需求,以下是适配@OneToMany场景的常用实现方案:

方案1:针对单关联做局部过滤(最适配你的场景)

直接在Country类的users关联属性上添加Hibernate原生的@org.hibernate.annotations.Where注解即可,查询Country加载关联用户列表时会自动跳过removed = true的记录:

@Entity(name = "Country")
@Table(name = "countries")
public class Country {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @org.hibernate.annotations.Where(clause = "removed = false")
    private List<User> users = new ArrayList<>();
}

注意:clause中写的是数据库表的字段名,不是实体属性名,如果你的removed属性对应数据库列名为is_removed,则需要写成clause = "is_removed = false"。

方案2:全局过滤所有User查询

如果希望所有查询User的场景(包括直接查询User、通过其他关联查询User)都自动过滤软删除记录,可以直接在User实体类上添加@Where注解:

@Entity(name = "User")
@Table(name = "users")
@org.hibernate.annotations.Where(clause = "removed = false")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private boolean removed;
}

方案3:动态开关过滤(灵活适配多场景)

如果需要在某些业务场景下查询到已软删除的User,可以使用@Filter注解实现动态可开关的过滤规则:

  1. 先在User实体上定义过滤器:
@Entity(name = "User")
@Table(name = "users")
@FilterDef(name = "filterRemovedUser", defaultCondition = "removed = false")
@Filter(name = "filterRemovedUser")
public class User {
    // 原有属性保持不变
}
  1. 在需要使用过滤的地方手动开启过滤器:
Session session = entityManager.unwrap(Session.class);
session.enableFilter("filterRemovedUser");
// 后续查询都会自动过滤软删除用户,调用session.disableFilter("filterRemovedUser")即可关闭过滤

你之前查到的@JoinColumn、@JoinColumnOrFormula确实仅适用于@ManyToOne关联场景,上述三种方案才是Hibernate官方提供的适配@OneToMany关联的过滤实现机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:45:00