JSRUN 用代码说话

Spring Data MongoDB + JSR-310 or Java 8 new Date APIs

编辑教程

While saving an object containing the new Java 8 java.time.LocalDateTime, the following error is thrown :

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

Tested

  1. Spring 4.3.2.RELEASE
  2. Spring Data MongoDB 1.9.2.RELEASE

Is Spring-data supporting the new Java 8 Date APIs (JSR-310)?

1. Spring Data + JSR-310

Yes, Spring-data supports the JSR-310 spec, with a custom convertor – Jsr310Converters, review the following code snippet :

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. Solution

The above Jsr310Converters will be enabled if you declared a Spring managed bean for MappingMongoConverter, and pass as an argument for MongoTemplate, review the following MongoConfig example :

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;
    }

    //...

}

The MappingMongoConverter extends AbstractMongoConverter, and the AbstractMongoConverter is an InitializingBean. If this declared as a Spring managed bean via @Bean, the afterPropertiesSet() will be fired, and registered all the default convertors, including the Jsr310Converters

3. FAQs

If the MappingMongoConverter is not managed by Spring (init with a new keyword like below), you must call the .afterPropertiesSet() manually.

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;

    }

    //...

References

  1. Github – Custom converters to spring-data-mongodb
  2. Spring IO – MappingMongoConverter JavaDoc
  3. Spring IO – CustomConversions JavaDoc
JSRUN闪电教程系统是国内最先开创的教程维护系统, 所有工程师都可以参与共同维护的闪电教程,让知识的积累变得统一完整、自成体系。 大家可以一起参与进共编,让零散的知识点帮助更多的人。
X
支付宝
9.99
无法付款,请点击这里
金额: 0
备注:
转账时请填写正确的金额和备注信息,到账由人工处理,可能需要较长时间
如有疑问请联系QQ:565830900
正在生成二维码, 此过程可能需要15秒钟