spring-数据-mongodb java.util.currency 问题

spring-data-mongodb issue with java.util.currency

我遇到了 link 中提到的相同问题: 我尝试了接受的答案。但它不起作用,我在行中收到 NullPointerException:

new CustomConversions(Arrays.asList(currencyToString, stringToCurrency));

所以我在新的 classes 中定义了转换器,如下所示:

@Component
public class CurrencyToStringConverter implements Converter<Currency,String>{

    /* (non-Javadoc)
     * @see com.fasterxml.jackson.databind.util.Converter#convert(java.lang.Object)
     */
    @Override
    public String convert(Currency arg0) {
        System.out.println("***INSIDE CurrencyToStringConverter***"+arg0);
        return arg0.getCurrencyCode();
    }
  }

@Component
public class StringToCurrencyConverter implements Converter<String,Currency>{
/* (non-Javadoc)
 * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
 */
    @Override
    public Currency convert(String arg0) {
        System.out.println("***INSIDE StringToCurrencyConverter***"+arg0);
        return Currency.getInstance(arg0);
    }
}

我在 "customConversions()" 中使用了它们,如下所示:

@Configuration
public class CustomMongoConfiguration extends AbstractMongoConfiguration {
    @Autowired
    private Environment env;

    @Bean
  @Override
  public CustomConversions customConversions() {
      System.out.println("***CUSTOM MONGO CONVERSIONS***");
    List<Converter<?,?>> converters=new ArrayList<>();
    converters.add(new CurrencyToStringConverter());
    converters.add(new StringToCurrencyConverter());

    return new CustomConversions(converters);
  }

    /* (non-Javadoc)
     * @see org.springframework.data.mongodb.config.AbstractMongoConfiguration#getDatabaseName()
     */
    @Override
    protected String getDatabaseName() {
        // TODO Auto-generated method stub
        String prop = env.getProperty("spring.data.mongodb.database");
        System.out.println("database naem:: "+prop);
        return prop;
    }

    /* (non-Javadoc)
     * @see org.springframework.data.mongodb.config.AbstractMongoConfiguration#mongo()
     */
    @Override
    @Bean
    public Mongo mongo() throws Exception {
        String prop = env.getProperty("spring.data.mongodb.host");
        System.out.println("host naem:: "+prop);
        return new MongoClient(prop);
    }
}

当 spring-boot 应用程序启动时,我可以看到以下打印的语句:

System.out.println("***CUSTOM MONGO CONVERSIONS***");
System.out.println("database naem:: "+prop);
System.out.println("host naem:: "+prop);

但是当我尝试从 MongoDB 获取我的对象时,它从不调用 Converter class 中的 "convert" 方法而且,我总是得到这个异常:

org.springframework.data.mapping.model.MappingException: No property null found on entity class java.util.Currency to bind constructor parameter to!
    at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:74)
    at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:63)
    at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:71)
    at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:251)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:231)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1186)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.access0(MappingMongoConverter.java:78)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1134)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getValueInternal(MappingMongoConverter.java:870)

我也关注了这个link:

Spring not using mongo custom converters

我按照 link 中的建议,在 class、CustomMongoConfiguration 中将 @Configuration 注释更改为 @Component。但它也不起作用。如果我使用@Component 注释,下面的语句会被打印多次。我不知道原因。

System.out.println("***CUSTOM MONGO CONVERSIONS***");
System.out.println("database naem:: "+prop);
System.out.println("host naem:: "+prop);

我正在使用 spring-引导版本 1.3。2.RELEASE。

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
</parent>

顺便说一句,我正在使用 application.properties 配置 mongodb 属性,而不是任何基于 java 的配置:

spring.data.mongodb.host=localhost
spring.data.mongodb.password=
spring.data.mongodb.port=27017
spring.data.mongodb.repositories.enabled=true
spring.data.mongodb.database=abcde

过去三天我一直在努力解决这个问题。谁能帮帮我。

Currency 转换已通过 b7131b 添加,并且从 1.9.0.M1.

开始可用

请将 @ReadingConverter@WritingConverter 添加到您的 Converter 实现中,以便 CustomConversions 而不仅仅是基础 ConversionService 知道这些。

我的错。问题在于之前插入 mongodb 的数据。之前以不正确的 "currency" 格式插入到 mongodb 中,即,不只是像 USD、GBP 这样的字符串值,它具有以下结构:

"currency" : {
                        "currencyCode" : "GBP",
                        "defaultFractionDigits" : 2,
                        "numericCode" : 826
                }

而不是像这样的简单代码:

 "currency" : "GBP"

在我编写转换器后,mongo 无法解析此结构并抛出此异常:

org.springframework.data.mapping.model.MappingException: No property null found on entity class java.util.Currency to bind constructor parameter to!
    at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:74)

我认为这个例外具有误导性。无论如何,我想通了。现在两个转换器都被调用了。

对我有用的最终解决方案:

@Configuration
public class CustomMongoConfiguration extends AbstractMongoConfiguration {
    @Autowired
    private MongoProperties mongoProps;

    @Bean
    @Override
    public CustomConversions customConversions() {
        System.out.println("***CUSTOM MONGO CONVERSIONS***");
        List<Converter<?, ?>> converters = new ArrayList<>();
        converters.add(new CurrencyToStringConverter());
        converters.add(new StringToCurrencyConverter());

        return new CustomConversions(converters);
    }

    @Override
    protected String getDatabaseName() {
        return mongoProps.getDatabase();
    }

    @Override
    @Bean
    public Mongo mongo() throws Exception {
        return new MongoClient(mongoProps.getHost(), mongoProps.getPort());
    }
}

根据 spring 文档,http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.converter-disambiguation,只有当源和目标都是本机类型时,您才需要将 @ReadingConverter@WritingConverter 放在转换器上(例如: String to Long 或 Long to String)。否则,您不需要在转换器上安装它们。在我的例子中,那些不是必需的,因为货币不是本机 mongo 类型。