JBoss Data Grid远程缓存ICKLE模糊查询报错求助
嘿,我来帮你搞定这个报错!先拆解下错误信息:ISPN028521: Full-text queries cannot be applied to property 'name' in type quickstart.Person unless the property is indexed and analyzed.
这个问题的核心是:你的name字段并没有被正确配置为支持全文分析的索引字段。虽然你在.proto文件的注释里写了类似@Field(index = true, store = true, analyze = true)的配置,但Infinispan(JBoss Data Grid)处理ProtoBuf定义时,完全不会识别这种注释形式的Java注解——它要求你用ProtoBuf原生的option语法来指定索引元数据。
具体解决步骤
1. 修正你的.proto文件
把索引配置改成Infinispan支持的ProtoBuf扩展选项,替换掉原来的注释注解。修改后的文件如下:
package quickstart; // 导入Infinispan的索引扩展元数据定义 import "infinispan/protobuf/metadata.proto"; // 标记整个Person实体为可索引 option (infinispan.metadata.entity).index = true; message Person { // 配置name字段:可索引、可存储、开启全文分析 required string name = 1 [(infinispan.metadata.field).index = true, (infinispan.metadata.field).store = true, (infinispan.metadata.field).analyze = true]; required int32 id = 2 [(infinispan.metadata.field).index = true, (infinispan.metadata.field).store = false]; optional string email = 3; optional string address = 4; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } // 标记子类型PhoneNumber为可索引 message PhoneNumber { required string number = 1 [(infinispan.metadata.field).index = true]; optional PhoneType type = 2 [default = HOME, (infinispan.metadata.field).index = false, (infinispan.metadata.field).store = false]; } repeated PhoneNumber phone = 5 [(infinispan.metadata.field).index = true, (infinispan.metadata.field).store = false]; }
关键改动说明:
- 导入
infinispan/protobuf/metadata.proto是配置索引的前提,它提供了Infinispan识别的扩展选项 - 用
option (infinispan.metadata.entity).index = true;替代原来的/* @Indexed */注释,标记整个实体可索引 - 每个字段通过
(infinispan.metadata.field)选项配置index/store/analyze属性,替代注释里的Java注解
2. 重新生成ProtoBuf实体类
修改完.proto后,一定要重新生成对应的Java实体类(用protoc工具或者Maven/Gradle的ProtoBuf插件),确保新的索引配置被嵌入到生成的代码中。
3. 确认缓存配置启用索引
还要检查Infinispan服务器的缓存配置,确保目标缓存已经开启索引功能,示例配置如下:
<cache-container> <local-cache name="personCache"> <indexing enabled="true" storage="local" path="indexes"> <indexed-entities> <indexed-entity>quickstart.Person</indexed-entity> </indexed-entities> </indexing> <encoding> <key media-type="application/x-protostream"/> <value media-type="application/x-protostream"/> </encoding> </local-cache> </cache-container>
4. 优化查询代码(可选但推荐)
你的查询语法是对的,但建议改用参数化查询避免潜在的注入风险:
private void queryPersonByNamebyIckelAndFuzzyDescription() { String namePattern = readConsole("Enter person name pattern: "); QueryFactory qf = Search.getQueryFactory(remoteCache); // 使用参数化查询更安全 Query query = qf.create("FROM quickstart.Person where name : ?1~2", namePattern); List<Person> results = query.list(); System.out.println("Found " + results.size() + " matches:"); for (Person p : results) { System.out.println(">> " + p); } }
为什么原来的写法不生效?
Infinispan处理ProtoBuf格式的远程缓存时,依赖的是ProtoBuf定义里的扩展元数据,而非Java注释中的Hibernate Search注解——那些注解只有在直接使用Java实体类映射时才会生效。对于远程缓存+ProtoBuf的场景,必须用ProtoBuf原生的option语法定义索引规则,服务器端才能正确识别并创建支持全文模糊查询的索引。
内容的提问来源于stack exchange,提问作者Debjyoti

