SpringデータMongoDB JSR-310またはJava 8の新しいDate API

Spring Data MongoDB + JSR-310またはJava 8の新しいDate API

新しいJava8java.time.LocalDateTimeを含むオブジェクトを保存しているときに、次のエラーがスローされます。

org.springframework.core.convert.ConverterNotFoundException:
    No converter found capable of converting
               from type [java.time.LocalDateTime] to type [java.util.Date]

テスト済み

  1. Spring 4.3.2.RELEASE

  2. Spring Data MongoDB 1.9.2.RELEASE

Spring-dataは新しいJava 8 Date API(JSR-310)をサポートしていますか?

1. Spring Data + JSR-310

はい、Spring-dataは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 toRegister = new ArrayList();

        // 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.example.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;
    }

    //...

}

MappingMongoConverterAbstractMongoConverterを拡張し、AbstractMongoConverterInitializingBeanです。 これが@Beanを介してSpringマネージドBeanとして宣言された場合、afterPropertiesSet()が起動され、Jsr310Convertersを含むすべてのデフォルトコンバーターが登録されます。

3. FAQs

MappingMongoConverterがSpringによって管理されていない場合(以下のようにnewキーワードを使用してinit)、.afterPropertiesSet()を手動で呼び出す必要があります。

MongoConfig.java

@Configuration
@ComponentScan(basePackages = {"com.example.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;

    }

    //...