Spring Data Solr自定义转换器处理实体属性失效问题咨询
我之前踩过Spring Data Solr自定义转换器失效的坑,尤其是处理LocalDate、Joda LocalDate还有Point这些非默认支持的类型时,折腾了好一阵才搞定,给你分享几个亲测有效的解决思路:
1. 确保自定义转换器正确注册到SolrCustomConversions
很多时候转换器不生效,核心原因是注册方式不对。你需要手动创建SolrCustomConversions实例,把自定义转换器加入其中,再通过配置类让Spring加载:
先写两个LocalDate的双向转换器示例:
// LocalDate转String(适配Solr存储) public class LocalDateToStringConverter implements Converter<LocalDate, String> { @Override public String convert(LocalDate source) { return source != null ? source.format(DateTimeFormatter.ISO_LOCAL_DATE) : null; } } // String转LocalDate(从Solr读取时转换) public class StringToLocalDateConverter implements Converter<String, LocalDate> { @Override public LocalDate convert(String source) { return source != null ? LocalDate.parse(source, DateTimeFormatter.ISO_LOCAL_DATE) : null; } }
然后在Solr配置类里注册所有需要的转换器:
@Configuration @EnableSolrRepositories(basePackages = "com.yourpackage.solr.repos") public class SolrConfig extends AbstractSolrConfiguration { @Override public SolrCustomConversions solrCustomConversions() { List<Converter<?, ?>> converters = new ArrayList<>(); // 加入LocalDate转换器 converters.add(new LocalDateToStringConverter()); converters.add(new StringToLocalDateConverter()); // 加入Joda LocalDate转换器 converters.add(new JodaLocalDateToStringConverter()); converters.add(new StringToJodaLocalDateConverter()); // 加入Point转换器 converters.add(new PointToStringConverter()); converters.add(new StringToPointConverter()); return new SolrCustomConversions(converters); } // 配置SolrClient @Bean public SolrClient solrClient() { return new HttpSolrClient.Builder("http://localhost:8983/solr").build(); } }
这里要注意:必须继承AbstractSolrConfiguration,或者手动配置SolrTemplate时,把自定义的SolrCustomConversions注入到MappingSolrConverter中,否则转换器不会生效。
2. 检查实体字段的注解配置
别给LocalDate/Joda LocalDate字段错误标注@Field(type = FieldType.DATE)——Solr的DATE类型只对应java.util.Date,你的转换器是把日期转成String存储,所以应该用@Field(type = FieldType.STRING),或者直接用@Field让转换器自动处理:
public class Product { @Id private String id; @Field("release_date") private LocalDate releaseDate; @Field("joda_create_date") private org.joda.time.LocalDate jodaCreateDate; @Field("store_location") private org.springframework.data.geo.Point storeLocation; // getter、setter省略 }
3. 保证转换器泛型完全匹配
Spring Data会严格匹配转换器的源类型和目标类型,比如处理Joda LocalDate时,转换器的泛型必须精确写org.joda.time.LocalDate,不能用父类或者模糊类型。举个Joda LocalDate转换器的例子:
public class JodaLocalDateToStringConverter implements Converter<org.joda.time.LocalDate, String> { @Override public String convert(org.joda.time.LocalDate source) { return source != null ? source.toString("yyyy-MM-dd") : null; } } public class StringToJodaLocalDateConverter implements Converter<String, org.joda.time.LocalDate> { @Override public org.joda.time.LocalDate convert(String source) { return source != null ? org.joda.time.LocalDate.parse(source) : null; } }
4. 确认SolrTemplate使用了正确的转换器
如果是手动创建SolrTemplate(而非依赖@EnableSolrRepositories自动生成),一定要确保SolrTemplate关联的MappingSolrConverter已经加载了自定义转换:
@Bean public SolrTemplate solrTemplate(SolrClient solrClient, SolrCustomConversions customConversions) { MappingSolrConverter converter = new MappingSolrConverter(new SimpleSolrMappingContext()); converter.setCustomConversions(customConversions); converter.afterPropertiesSet(); return new SolrTemplate(solrClient, converter); }
5. 从日志排查加载情况
启动应用时,留意日志里有没有SolrCustomConversions相关的加载信息,比如是否打印了“Registered custom converters: ...”的内容。如果没有,说明你的配置类没被Spring扫描到,或者转换器注册逻辑有问题。
如果出现类似Cannot convert value of type 'java.time.LocalDate' to required type 'java.lang.String'的错误,那肯定是转换器没生效,回到前面的步骤逐一排查注册、泛型、注解配置。
内容的提问来源于stack exchange,提问作者Jan Tomáššek

