SpringデータMongoDB JSR-310またはJava 8の新しいDate API
新しいJava 8 `java.time.LocalDateTime`を含むオブジェクトを保存しているときに、次のエラーがスローされます。
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting
from type[java.time.LocalDateTime]to type[java.util.Date]....
テスト済み
. Spring 4.3.2.RELEASE
. SpringデータMongoDB 1.9.2.RELEASE
Spring-dataは新しいJava 8 Date API(JSR-310)をサポートしていますか?
=== 1. Springデータ+ JSR-310
はい、SpringのデータはJSR-310仕様をカスタムコンバータでサポートしています - Jsr310Converters`、次のコードスニペットを見直してください:
CustomConversions.java
package org.springframework.data.mongodb.core.convert;
public class CustomConversions {
/** **
** Creates a new {@link CustomConversions} instance registering the given converters.
**
** @param converters
** / public CustomConversions(List<?> converters) {
//... List<Object> toRegister = new ArrayList<Object>();
//Add user provided converters to make sure they can override the defaults toRegister.addAll(converters); toRegister.add(CustomToStringConverter.INSTANCE); toRegister.addAll(MongoConverters.getConvertersToRegister()); toRegister.addAll(JodaTimeConverters.getConvertersToRegister()); toRegister.addAll(GeoConverters.getConvertersToRegister()); toRegister.addAll(Jsr310Converters.getConvertersToRegister()); toRegister.addAll(ThreeTenBackPortConverters.getConvertersToRegister());
for (Object c : toRegister) {
registerConversion(c);
}
//... }
=== 2.解決策
上記の `Jsr310Converters`は` MappingMongoConverter`のSpringマネージドBeanを宣言し、 `MongoTemplate`の引数として渡す場合に有効になります。次のMongoConfigの例を見直してください:
MongoConfig.java
....//...
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
@Configuration
@ComponentScan(basePackages = {"com.mkyong.db"})
public class MongoConfig {
//...
@Autowired
MongoDbFactory mongoDbFactory;
@Bean
public MongoTemplate mongoTemplate() throws Exception {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, getDefaultMongoConverter());
return mongoTemplate;
}
@Bean
public MappingMongoConverter getDefaultMongoConverter() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(
new DefaultDbRefResolver(mongoDbFactory), new MongoMappingContext());
return converter;
}
//...
}
MappingMongoConverter`は
AbstractMongoConverter`を拡張し、
AbstractMongoConverter`は
InitializingBean`です。これが
@ Bean`を介してSpring管理Beanとして宣言された場合、
afterPropertiesSet()
が起動され、
Jsr310Converters`を含むすべてのデフォルトコンバータが登録されます。
3.よくある質問
MappingMongoConverter`がSpring(以下のような
new`キーワードを持つinit)によって管理されていない場合、 `.afterPropertiesSet()`を手動で呼び出さなければなりません。
MongoConfig.java
@Configuration
@ComponentScan(basePackages = {"com.mkyong.db"})
public class MongoConfig {
@Autowired
MongoDbFactory mongoDbFactory;
@Bean
public MongoTemplate mongoTemplate() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(
new DefaultDbRefResolver(mongoDbFactory), new MongoMappingContext());
//CALL THIS MANULLY, so that all the default convertors will be registered!
converter.afterPropertiesSet();
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, converter);
return mongoTemplate;
}
//...
参考文献
-
https://gist.github.com/harlanji/1179718
[Github – カスタムコンバーター
spring-data-mongodb]。
http://docs.spring.io/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/core/convert/MappingMongoConverter.html
[Spring
IO – MappingMongoConverter JavaDoc]。
http://docs.spring.io/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/core/convert/CustomConversions.html
[Spring
IO – CustomConversions JavaDoc]