You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 01:47:52