Hibernate Search 6:如何过滤IndexedEmbedded关联的软删除Role实体
解决方法:过滤@IndexedEmbedded中的软删除关联实体
不需要借助类似RoutingBridge的机制,Hibernate Search本身提供了直接的方式来过滤嵌入索引的关联实体,下面是两种常用实现方案:
方案一:通过计算属性返回活跃角色列表
直接在User实体中添加一个返回仅活跃角色的计算属性,将@IndexedEmbedded标注在这个属性上,替代原来的roles字段:
@Entity @Indexed public class User { @FullTextField String name; // 原关联字段,不添加@IndexedEmbedded @OneToMany(mappedBy = "user") List<Role> roles; // 计算属性:返回状态非DELETED的角色 @Transient @IndexedEmbedded public List<Role> getActiveRoles() { return roles.stream() .filter(role -> !"DELETED".equals(role.getStatus())) .collect(Collectors.toList()); } // 省略getter/setter } @Entity public class Role { @FullTextField String name; String status; // 省略关联字段及getter/setter }
这种方式简单直观,索引时Hibernate Search会自动调用getActiveRoles()方法获取需要嵌入的角色列表。
方案二:使用Hibernate Search过滤器机制
通过定义过滤器规则,在@IndexedEmbedded中指定过滤条件,只索引符合要求的Role实体:
1. 定义过滤器规则
在User实体上定义过滤器,同时在Role实体上指定过滤条件:
@FilterDef(name = "excludeDeletedRoles", parameters = @ParamDef(name = "deletedStatus", type = String.class)) @Entity @Indexed public class User { @FullTextField String name; @IndexedEmbedded(filter = @Filter(name = "excludeDeletedRoles", parameters = @Parameter(name = "deletedStatus", value = "'DELETED'"))) @OneToMany(mappedBy = "user") List<Role> roles; // 省略getter/setter } @Filter(name = "excludeDeletedRoles", condition = "status <> :deletedStatus") @Entity public class Role { @FullTextField String name; String status; // 省略关联字段及getter/setter }
2. 启用过滤器
确保在索引时过滤器被启用,你可以通过Hibernate Search的配置或者在索引操作时显式启用:
// 示例:在批量索引时启用过滤器 SearchSession searchSession = Search.session(entityManager); searchSession.massIndexer(User.class) .enableFilter("excludeDeletedRoles") .startAndWait();
补充说明
RoutingBridge的作用是控制文档的路由(比如分配到不同的索引分片),和过滤关联实体的需求不匹配,所以不需要使用它来实现这个功能。
内容的提问来源于stack exchange,提问作者phingage
相关产品推荐
相关产品推荐

