简体   繁体   English

Spring-Data-MongoDB:使用自定义转换器升级到2.0.7后,无法从类型转换

[英]Spring-Data-MongoDB: Failed to convert from type after upgrade to 2.0.7 with custom converter

I just upgraded to Spring Boot 2.0.2 today and as part of that also to Spring-Data-MongoDB 2.0.7. 我今天刚刚升级到Spring Boot 2.0.2,作为升级的一部分,我还升级到了Spring-Data-MongoDB 2.0.7。

I have the following entity: 我有以下实体:

@Document
@Data
public class User {
private String username;
private String password;
private List<String> authorities;

    public User(String username, String password, List<String> authorities) {
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }
}

In a test of mine I insert a new User using the following: 在我的测试中,我使用以下命令插入新用户:

mongoTemplate.save(new User("testuser", "$2a$04$OuKj.lXzPxlwgr2Jy28E4ehHuxnVZ7BuL46qX9fd6vAijcDN6UeHe", Collections.singletonList("user")));

This worked perfectly when using Spring Boot 2.0.1 (respectively Spring-Data-MongoDB 2.0.6). 当使用Spring Boot 2.0.1时(分别是Spring-Data-MongoDB 2.0.6),这完美地工作了。 With the upgraded Spring-Data-MongoDB version, I get the following error: 使用升级的Spring-Data-MongoDB版本,出现以下错误:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.ZonedDateTime] for value 'testuser'; nested exception is java.time.format.DateTimeParseException: Text 'testuser' could not be parsed at index 0

    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:46)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleWrite(MappingMongoConverter.java:849)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeSimpleInternal(MappingMongoConverter.java:829)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeProperties(MappingMongoConverter.java:488)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:462)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:436)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:391)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:86)
    at org.springframework.data.mongodb.core.MongoTemplate.toDocument(MongoTemplate.java:1070)
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1253)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1201)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1185)
....
Caused by: java.time.format.DateTimeParseException: Text 'testuser' could not be parsed at index 0
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
    at at.riag.scanpay.config.MongoConfig$StringToZonedDateTime.convert(MongoConfig.java:34)
    at at.riag.scanpay.config.MongoConfig$StringToZonedDateTime.convert(MongoConfig.java:28)
    at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:385)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
    ... 71 more

So it seems like, it wants to convert the username to a ZonedDateTime . 如此看来,它想将username转换为ZonedDateTime The problem could be my MongoConfig, where I have custom converters for ZonedDateTime : 问题可能出在我的MongoConfig上,那里有ZonedDateTime自定义转换器:

@Configuration
public class MongoConfig {

    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

    @Bean
    public MongoCustomConversions customConversions(){
        List<Converter<?,?>> converters = new ArrayList<>();
        converters.add(ZonedDateTimeToStringConverter.INSTANCE);
        converters.add(StringToZonedDateTime.INSTANCE);
        return new MongoCustomConversions(converters);
    }

    enum StringToZonedDateTime implements Converter<String, ZonedDateTime> {

        INSTANCE;

        @Override
        public ZonedDateTime convert(String source) {
            return ZonedDateTime.parse(source, dateTimeFormatter);
        }
    }

    enum ZonedDateTimeToStringConverter implements Converter<ZonedDateTime, String> {

        INSTANCE;

        @Override
        public String convert(ZonedDateTime source) {
            return dateTimeFormatter.format(source);
        }
    }
}

These converters should not be used for a plain String of course but it seems that it is triggered when using the new Spring Data MongoDB version. 当然,这些转换器不应用于纯字符串,但似乎在使用新的Spring Data MongoDB版本时会触发它。 Can anyone please point me to the problem I am having with my code or is there a problem with the latest version? 有人可以指出我的代码问题吗,还是最新版本有问题?

Thanks in advance! 提前致谢!

Spring Data MongoDB 2.0.7 considers ZonedDateType as simple type. Spring Data MongoDB 2.0.7将ZonedDateType视为简单类型。 You need to disambiguate converters into reading and writing converters by adding @ReadingConverter / @WritingConverter . 您需要通过添加@ReadingConverter / @WritingConverter来消除转换器对读写转换器的@WritingConverter

In your arrangement above, the framework attempts to convert all String values into ZonedDateTime . 在上述安排中,框架尝试将所有String值转换为ZonedDateTime Instead, you want to represent rather ZonedDateTime objects as String in your MongoDB. 相反,您想在MongoDB ZonedDateTime对象表示为String So adding @WritingConverter to ZonedDateTimeToStringConverter and @ReadingConverter to the other one fixes your issue. 因此,将@WritingConverter添加到ZonedDateTimeToStringConverter并将@ReadingConverter添加到另一个解决了您的问题。

I had the same problem after updating it to version 2. 更新到版本2后,我遇到了同样的问题。

My problem was that we were using DBObject in the converter instead of org.bson.Document . 我的问题是,我们在转换器中使用DBObject而不是org.bson.Document For example: 例如:

public class MyCustomMappingConverter implements Converter<DBObject, MyClass>

I solved it by changing it to: 我将其更改为:

public class MyCustomMappingConverter implements Converter<Document, MyClass>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM