在Infinispan中用@Text注解生成索引且不缓存文本内容可行吗?
解决思路与实现方案
1. 移除实体中的text存储字段
直接把record里的text字段删掉,改成动态计算的方法——毕竟我们要的是它生成的索引内容,不是把它存在缓存里。
修改后的代码:
@Proto @Indexed public record CachedMessage( @Basic long userId, @Basic long messageId, @Basic long creationDate, @Basic long readingDate ) { // 动态生成搜索用的文本内容,逻辑和之前拼接text的逻辑保持一致 public String getText() { DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String creationDateStr = dateFormatter.format(Instant.ofEpochMilli(creationDate).atZone(ZoneId.systemDefault())); String readingDateStr = dateFormatter.format(Instant.ofEpochMilli(readingDate).atZone(ZoneId.systemDefault())); return String.format("userId:%d messageId:%d creationDate:%s readingDate:%s", userId, messageId, creationDateStr, readingDateStr); } }
2. 让索引框架识别动态生成的文本
如果用的是Hibernate Search这类支持注解配置的索引框架,直接在getText()方法上标注@Text注解,告诉框架这个方法的返回值要作为搜索索引的文本来源:
@Proto @Indexed public record CachedMessage( @Basic long userId, @Basic long messageId, @Basic long creationDate, @Basic long readingDate ) { @Text // 索引框架会自动调用这个方法获取索引文本 public String getText() { // 拼接逻辑不变 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String creationDateStr = dateFormatter.format(Instant.ofEpochMilli(creationDate).atZone(ZoneId.systemDefault())); String readingDateStr = dateFormatter.format(Instant.ofEpochMilli(readingDate).atZone(ZoneId.systemDefault())); return String.format("userId:%d messageId:%d creationDate:%s readingDate:%s", userId, messageId, creationDateStr, readingDateStr); } }
3. 适配序列化逻辑
因为用了@Proto注解做Protocol Buffers序列化,现在record里没有text字段,序列化后的数据里自然不会包含它,直接节省了缓存的内存和存储体积。如果索引需要在对象加载后生成,只要确保索引逻辑是调用对象的getText()方法,而不是从序列化数据里读取就行。
核心注意事项
- 保持
getText()的拼接逻辑和之前的text字段生成逻辑完全一致,避免搜索行为出现偏差。 - 确认你的索引框架支持从方法返回值生成索引,而不是只认实体的存储字段。
- 这种方式下,
text内容不会占用缓存的持久化内存,只有在需要生成索引时才临时计算,完美契合内存节省的需求。
内容的提问来源于stack exchange,提问作者Rafael Rocha
相关产品推荐
相关产品推荐

