以编程方式设置MongoDb转换器
我正在尝试使用带有spring-data-mongodb的自定义转换器。 我想以编程方式创建它,但我收到以下错误:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type org.joda.time.LocalDate to type java.lang.String at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:475) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175) at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:154) .... ....
以下是失败的代码段:
Mongo mongo = new Mongo(); MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo, "database"); List converters = new ArrayList(); converters.add(new LocalDateWriteConverter()); converters.add(new LocalDateReadConverter()); CustomConversions customConversions = new CustomConversions(converters); MappingContext mappingContext = new SimpleMongoMappingContext(); MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(mongoDbFactory, mappingContext); mappingMongoConverter.setCustomConversions(customConversions); MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, mappingMongoConverter); MongoDbEvent mongoEvent = new MongoDbEvent(new LocalDate(2012, 12, 8)); mongoTemplate.insert(mongoEvent);
这是我的转换器类:
class LocalDateReadConverter implements Converter { @Override public LocalDate convert(String s) { // Conversion code omitted. } } class LocalDateWriteConverter implements Converter { @Override public String convert(LocalDate localDate) { // Conversion code omitted. } }
我试图坚持的课程看起来像这样:
import org.joda.time.LocalDate; public class MongoDbEvent { private String id; private LocalDate date; public MongoDbEvent(LocalDate date) { this.date = date; } public String getId() { return id; } public LocalDate getDate() { return date; } @Override public String toString() { return "MongoDbEvent{" + "id='" + id + '\'' + ", date=" + date + '}'; } }
OP的答案可能有点迟,但我今天遇到了同样的问题并找到了解决方案……
要以编程方式进行设置,需要在使用之前调用MongoMappingConverter.afterPropertiesSet()
。 我通过阅读MongoTemplate.getDefaultMongoConverter(MongoDbFactory)
的代码意识到了这一点。
这是一个例子:
MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory, context); converter.setTypeMapper(mapper); converter.setCustomConversions(new CustomConversions( Arrays.asList( new TimeZoneReadConverter(), new TimeZoneWriteConverter() ) )); converter.afterPropertiesSet(); MongoTemplate template = new MongoTemplate(mongoDbFactory, converter);
只是一个抬头。 我在使用Java配置的spring-data-mongodb 1.5.1.RELEASE
上遇到了这个问题。 由于一些课程已经改变,我正在发布我的解决方案。
在使用@Configuration
注释的配置类中添加以下定义:
@Bean public Mongo mongo() throws Exception { MongoPropertiesResolver resolver = mongoResolver(); return new MongoClient(resolver.getUrl()); } @Bean public MongoDbFactory mongoDbFactory() throws Exception { return new SimpleMongoDbFactory(mongo(), "database"); } @Bean public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(mongoDbFactory(), mongoConverter()); } @Bean public CustomConversions customConversions() { List> converters = new ArrayList>(); converters.add(new TimeZoneReadConverter()); converters.add(new TimeZoneReadConverter()); return new CustomConversions(converters); } @Bean public MappingMongoConverter mongoConverter() throws Exception { MongoMappingContext mappingContext = new MongoMappingContext(); DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory()); MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext); mongoConverter.setCustomConversions(customConversions()); return mongoConverter; }
如何使用自定义转换器自定义mongo详细说明如下:
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-configuration
我注入了默认配置值,因此我可以从application.properties配置设置中受益。
@Configuration public class MongoConfiguration extends AbstractMongoConfiguration { @Value("${spring.data.mongodb.database:test}") String database; @Value("${spring.data.mongodb.host:localhost}:${spring.data.mongodb.port:27017}") String host; @Override protected String getDatabaseName() { return database; } @Override public Mongo mongo() throws Exception { return new MongoClient(host); } @Bean @Override public CustomConversions customConversions() { List> converterList = new ArrayList>(); converterList.add(new MongoColorWriter()); converterList.add(new MongoColorReader()); return new CustomConversions(converterList); } }
随着java 8中java.time包的引入,我在新包中使用新的LocalDate和LocalDateTime类遇到了类似的问题。 这就是我解决它的方式:
我为所有这四种转换选项编写了一个转换器:
- DateToLocalDateTimeConverter
- DateToLocalDateConverter
- LocalDateTimeToDateConverter
- LocalDateToDateConverter
这是一个例子
public class DateToLocalDateTimeConverter implements Converter { @Override public LocalDateTime convert(Date source) { return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault()); } }
然后通过将其包含在mongodb连接的xml配置中,我能够使用mongodb在java 8日期工作(记得添加所有转换器):
自org.springframework.data:spring-data-commons:1.13.3.RELEASE
以来,这里是如何使用自定义转换器以编程方式创建MongoTemplate
public MongoTemplate mongoTemplate(String mongoUri) throws Exception { MongoDbFactory factory = new SimpleMongoDbFactory(new MongoClientURI(mongoUri)); CustomConversions conversions = new CustomConversions( Arrays.asList(new FooWriteConverter(), new FooReadConverter())); MongoMappingContext mappingContext = new MongoMappingContext(); DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); MappingMongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext); mongoConverter.setCustomConversions(conversions); mongoConverter.afterPropertiesSet(); return new MongoTemplate(factory, mongoConverter); }
转换器(实现省略)
class FooWriteConverter implements Converter { ... } class FooReadConverter implements Converter { ... }