Spring Data集成多数据源时Elasticsearch出现误导性报错如何解决?
问题根因
Spring Data Elasticsearch 的持久化属性解析逻辑默认仅识别实体类中声明的成员变量,不会将仅存在getter方法的虚拟属性判定为合法的持久化字段,这就是你在其他数据源正常、仅ES数据源报错的核心原因。你之前尝试的@Primary、扫描路径配置、@Transient注解都和属性解析逻辑无关,因此无法生效。
可行解决方案
方案1:放弃方法名派生查询,使用
@Query注解手动指定ES查询DSL
直接在Repository的查询方法上标注@Query,写死要查询的ES索引实际字段名,不用和实体类属性绑定,示例如下:public interface MyRecordDao extends CrudRepository<MyRecord, String> { // 大括号内是ES原生查询DSL,?0对应方法的第一个入参,my_member_attribute替换为你ES索引中的实际字段名 @Query("{\"term\": {\"my_member_attribute\": ?0}}") List<MyRecord> findByMyMemberAttribute(String myMemberAttribute); }这种方案改动最小,不需要修改实体类结构。
方案2:调整实体类适配ES属性解析规则
给实体类添加对应名称的私有成员变量,添加@Field注解指定ES字段映射,不需要编写setter方法,也不需要在业务逻辑中给该变量赋值,原有getter逻辑保持不变即可:@Document(indexName = "my_record") public class MyRecord { // 新增成员变量,不需要加@Transient @Field(name = "my_member_attribute", type = FieldType.Keyword) private String myMemberAttribute; // 你原有自定义逻辑的getter保持不变 public String getMyMemberAttribute() { // 原有计算逻辑 return xxx; } // 不需要写setMyMemberAttribute方法 }只要存在对应名称的成员变量,Spring Data ES解析查询方法时就不会抛出属性不存在的错误。你之前加成员变量无效大概率是误加了
@Transient注解,或者@Field指定的字段名和ES索引实际字段不匹配。方案3:使用更低层级的API查询
直接注入ElasticsearchOperations或ElasticsearchRestTemplate手动构造查询条件,完全脱离Repository方法名的解析规则,适合复杂查询场景。
内容的提问来源于stack exchange,提问作者n2qzshce
相关产品推荐
相关产品推荐

