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注解实现动态可开关的过滤规则:
- 先在User实体上定义过滤器:
@Entity(name = "User") @Table(name = "users") @FilterDef(name = "filterRemovedUser", defaultCondition = "removed = false") @Filter(name = "filterRemovedUser") public class User { // 原有属性保持不变 }
- 在需要使用过滤的地方手动开启过滤器:
Session session = entityManager.unwrap(Session.class); session.enableFilter("filterRemovedUser"); // 后续查询都会自动过滤软删除用户,调用session.disableFilter("filterRemovedUser")即可关闭过滤
你之前查到的@JoinColumn、@JoinColumnOrFormula确实仅适用于@ManyToOne关联场景,上述三种方案才是Hibernate官方提供的适配@OneToMany关联的过滤实现机制。
内容的提问来源于stack exchange,提问作者user471011
相关产品推荐
相关产品推荐

