以编程方式设置 MongoDb 转换器
Posted
技术标签:
【中文标题】以编程方式设置 MongoDb 转换器【英文标题】:Set MongoDb converter programmatically 【发布时间】:2012-11-26 16:05:37 【问题描述】:我正在尝试使用带有 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)
....
....
下面是失败的代码sn-p:
Mongo mongo = new Mongo();
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongo, "database");
List<Converter> 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<String, LocalDate>
@Override
public LocalDate convert(String s)
// Conversion code omitted.
class LocalDateWriteConverter implements Converter<LocalDate, String>
@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 +
'';
【问题讨论】:
【参考方案1】:对我来说,它是将我的转换器注册为读者而不是作家。要解决此问题,您需要将 @WritingConverter 注释添加到转换器类
@Component
@WritingConverter
public class NoteWriterConverter implements Converter<Note, DBObject>
@Override
public DBObject convert(Note source)
DBObject obj = new BasicDBObject();
obj.put("title", source.getTitle());
obj.put("reviewDate", source.getReviewDate());
obj.removeField("_class");
return obj;
【讨论】:
【参考方案2】:由于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<Foo, DBObject> ...
class FooReadConverter implements Converter<DBObject, Foo> ...
【讨论】:
【参考方案3】:这里详细描述了如何使用自定义转换器自定义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<Converter<?, ?>> converterList = new ArrayList<Converter<?, ?>>();
converterList.add(new MongoColorWriter());
converterList.add(new MongoColorReader());
return new CustomConversions(converterList);
【讨论】:
分享的链接很有帮助。【参考方案4】:只是提个醒。我在spring-data-mongodb 1.5.1.RELEASE
using Java Configuration 上遇到了这个问题。由于某些课程发生了变化,我将发布我的解决方案。
在带有@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<Converter<?, ?>> converters = new ArrayList<Converter<?, ?>>();
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;
【讨论】:
构造函数 SimpleMongoDbFactory(Mongo, String) 已弃用 - 我使用的是 Spring Boot 1.3.2 感谢代码示例,这有助于我在尝试使用 Fongo 组合一些单元测试时设置一些自定义转换器。【参考方案5】:随着 java.time 包在 java 8 中的引入,我在使用新包中的新 LocalDate 和 LocalDateTime 类时遇到了类似的问题。 我就是这样解决的:
我为所有这 4 个转换选项编写了一个转换器:
DateToLocalDateTime 转换器 DateToLocalDateConverter LocalDateTimeToDateConverter LocalDateToDateConverter这是一个例子
public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime>
@Override
public LocalDateTime convert(Date source)
return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
然后通过将它包含在 mongodb 连接的 xml 配置中,我能够使用 mongodb 在 java 8 日期中工作(记得添加所有转换器):
<mongo:mapping-converter>
<mongo:custom-converters>
<mongo:converter>
<bean class="package.DateToLocalDateTimeConverter" />
</mongo:converter>
</mongo:custom-converters>
</mongo:mapping-converter>
【讨论】:
【参考方案6】:这个答案对于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);
【讨论】:
非常感谢!正如我在 spring-data 的单元测试中看到的.afterPropertiesSet();
一样,我没有给予足够的重视......
救世主!! :) 谢谢你,虽然我仍然需要了解文档。以上是关于以编程方式设置 MongoDb 转换器的主要内容,如果未能解决你的问题,请参考以下文章
在哪里以编程方式设置 TableViewController 的 UIBarButtonItem 和单元格“segue”