Infinispan如何通过代码为POJO配置嵌入式缓存索引?
Infinispan 11+ 嵌入式缓存POJO编程式索引配置方案
问题背景
Infinispan 11版本前,可通过SearchMapping编程式定义嵌入式缓存POJO索引,但11及之后版本该方法失效,且官方文档存在错误引用废弃Hibernate类的问题。按非官方资料编写的代码运行时出现以下错误:
org.infinispan.commons.CacheConfigurationException: ISPN000404: The configured entity class MyData is not indexable. Please remove it from the indexing configuration.
错误原因
- 系统属性
hibernate.search.mapping.configurer设置时机晚于缓存管理器初始化,导致配置未被加载 - 冗余调用
addIndexedEntity(MyData.class),与MappingConfigurer的配置冲突 - 缓存配置的构建和启动步骤存在疏漏
修正后的完整代码
import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.IndexStorage; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.query.hibernate.orm.HibernateOrmMappingConfigurationContext; import org.infinispan.query.hibernate.orm.HibernateOrmSearchMappingConfigurer; import org.hibernate.search.mapper.pojo.mapping.definition.programmatic.ProgrammaticMappingConfigurationContext; import org.hibernate.search.mapper.pojo.mapping.definition.programmatic.TypeMappingStep; import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.backend.types.Sortable; public class IndexConfigDemo { // 自定义POJO类,需实现Serializable public static class MyData implements java.io.Serializable { private Long expiry; // 省略getter/setter public Long getExpiry() { return expiry; } public void setExpiry(Long expiry) { this.expiry = expiry; } } // 实现索引映射配置器 public static class MySearchMappingConfigurer implements HibernateOrmSearchMappingConfigurer { @Override public void configure(HibernateOrmMappingConfigurationContext context) { ProgrammaticMappingConfigurationContext mapping = context.programmaticMapping(); TypeMappingStep dataMapping = mapping.type(MyData.class); dataMapping.indexed(); // 标记类为可索引 // 配置expiry字段的索引属性 dataMapping.property("expiry") .genericField() .projectable(Projectable.YES) .sortable(Sortable.YES); } } public static void main(String[] args) { // 1. 先设置系统属性,确保缓存管理器初始化时能加载配置器 System.setProperty("hibernate.search.mapping.configurer", "class:IndexConfigDemo.MySearchMappingConfigurer"); // 2. 初始化缓存管理器 EmbeddedCacheManager cacheManager = new DefaultCacheManager(); // 3. 构建缓存配置 ConfigurationBuilder builder = new ConfigurationBuilder(); builder.indexing() .enabled(true) .storage(IndexStorage.FILESYSTEM) .path("/some/path"); // 索引存储路径 // 4. 创建并启动缓存 Configuration cacheConfig = builder.build(); cacheManager.defineConfiguration("myCache", cacheConfig); var cache = cacheManager.getCache("myCache"); // 5. 测试缓存与索引 MyData data = new MyData(); data.setExpiry(System.currentTimeMillis()); cache.put("key1", data); } }
关键说明
- 系统属性设置时机:必须在
DefaultCacheManager实例化之前设置,否则Hibernate Search无法加载自定义配置器 - 移除冗余配置:
addIndexedEntity(MyData.class)需删除,因为dataMapping.indexed()已将类标记为可索引,重复配置会触发冲突检查 - POJO序列化要求:MyData必须实现
java.io.Serializable,这是Infinispan缓存对象的强制条件 - 索引存储选型:根据场景选择
IndexStorage.FILESYSTEM(持久化)或IndexStorage.MEMORY(内存级)等存储类型
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

