Problem Description: We all know that data that involves money must be stored using the BigDecimal type, and there is still a precision problem with querying MONGO today, although I used the big decimal type in my code, but I used the double type in MONGO. My initial inference was that Mongotemplate had a problem with the type conversion, or because it was stored using a double type in MongoDB. But I can't decide mongodb so I can only start with the code to do rounding.
Workaround: Customize a Customer-convert so that the mongotemplate is converted at mapping, so that it does not need to be modified in various places. Here is also a problem is the original use of springboot, so there is no mongo.xml configuration. There is no place to register your own convert. I finally made my own new mongotemplate in the Java configuration and injected it into the IOC container, so I had a chance to register for convert when I was new mongotemplate.
Here is the specific code
@Configuration
Public class MongodbConfiguration {
@Value("${spring.data.mongodb.uri}")
Private String mongoUrl;
@Bean
Public MongoMappingContext mongoMappingContext() {
MongoMappingContext mappingContext = new MongoMappingContext();
Return mappingContext;
}
@Bean
@Primary
Public MongoDbFactory dbFactory1() throws UnknownHostException {
Return new SimpleMongoDbFactory(new MongoClientURI(mongoUrl));
}
@Bean
Public MappingMongoConverter mappingMongoConverter1() throws Exception {
DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.dbFactory1());
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext());
List<Converter> converters = new ArrayList<>();
Converters.add(new DoubleToBigDecimalConverter());
CustomConversions customConversions = new CustomConversions(converters);
converter.setCustomConversions(customConversions);
Return converter;
}
@Bean
@Primary
Public MongoTemplate mongoTemplate() throws Exception {
Return new MongoTemplate(this.dbFactory1(), this.mappingMongoConverter1());
}
}
@ReadingConverter
Class DoubleToBigDecimalConverter implements Converter<Double,BigDecimal> {
// Here we can uniformly round the double type and specify two decimal places.
@Override
Public BigDecimal convert(Double source) {
BigDecimal bigDecimal = BigDecimal.valueOf(source);
Return bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP);
}
}
How to convert BigDecimal to Double in SPRING-DATA-MONGODB framework