Hibernate Search FullTextFilter缓存不生效问题求助
针对你遇到的过滤器缓存失效问题,结合你给出的实体类配置和过滤器定义,咱们从几个核心方向排查:
1. 确保过滤器工厂是无状态实现
你配置的cache = FilterCacheModeType.INSTANCE_ONLY要求过滤器工厂必须是无状态的——也就是说工厂类不能包含任何会随请求变化的成员变量。从你贴的代码看,OnlyActiveFilterFactory里有私有变量定义,要是这个变量会在不同请求中被修改,缓存逻辑就会直接失效。
正确的无状态过滤器工厂示例:
public class OnlyActiveFilterFactory { // 禁止定义随请求变化的成员变量 public Query getQuery(FullTextFilter filter) { // 直接返回固定查询逻辑,匹配activo为true的记录 return new TermQuery(new Term("activo", Boolean.TRUE.toString())); } }
如果需要接收参数,必须通过filter.getParameter("paramName")获取,不能将参数存在工厂的成员变量中。
2. 检查过滤器的启用方式是否正确
缓存生效的前提是你通过Hibernate Search的官方API启用过滤器,而非手动实例化工厂类。正确的使用方式如下:
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, Article.class); // 启用定义好的onlyActive过滤器 fullTextQuery.enableFilter("onlyActive"); List<Article> results = fullTextQuery.list();
要是每次查询都自行new过滤器工厂实例,Hibernate Search的缓存机制根本不会介入工作。
3. 排查全局缓存配置是否被禁用
有时候全局配置会覆盖单个过滤器的缓存设置,比如在persistence.xml或者hibernate.properties里如果存在这条配置:
hibernate.search.filter.cache.enabled = false
会直接禁用所有过滤器的缓存,把它改成true或者删除这条配置即可。
4. 验证索引字段与过滤器查询的匹配性
你的activo字段是Boolean类型,标注的@Field(analyze = Analyze.NO),Lucene会把它存储为字符串"true"或"false"。要是你的过滤器查询用了错误的Term(比如用1/0代替字符串值),会导致过滤器一直返回空结果,看起来像是缓存没生效,实际是查询逻辑不匹配索引数据。
确保过滤器里的查询语句是:
return new TermQuery(new Term("activo", Boolean.TRUE.toString()));
5. 检查Hibernate Search版本兼容性
部分旧版本的Hibernate Search在INSTANCE_ONLY缓存模式上存在bug,比如5.8.x之前的某些版本。如果你的版本比较老旧,建议升级到最新的稳定版(比如5.11.x系列或者6.x系列)。
6. 开启日志确认缓存命中情况
开启DEBUG级别的Hibernate Search过滤器日志,能直接看到缓存是否命中:
log4j.logger.org.hibernate.search.filter=DEBUG
日志里会出现Cache hit for filter instance(缓存命中)或者Creating new filter instance(创建新实例,未命中)的信息,帮你确认缓存是否真的未生效。
内容的提问来源于stack exchange,提问作者Joaquín L. Robles

