Custom converter for Mongodb and Spring Data for BigDecimal type

Recently I found that MongoDB does not support java's java.math.BigDecimal as you can read in the official spring data mongodb documentation

As it turns out java.math.BigDecimal will be converted to java.lang.String when saved to the database and parsed back to BigDecimal which in most cases I guess it's alright

However as I found out things get broken when trying to perform range queries on this field such as : $gte, $lte you will get inconsistent results since MongoDB sees this as a String

Luckily this can be easily fixed by creating 2 custom converters (one for each side), below is how I've done it :

1. Define custom converters by implementing the appropriate interface

import org.springframework.core.convert.converter.Converter;

import java.math.BigDecimal;

public class BigDecimalToDoubleConverter implements Converter<BigDecimal, Double> {

    @Override
    public Double convert(BigDecimal source) {
        return source.doubleValue();
    }
}

import org.springframework.core.convert.converter.Converter;

import java.math.BigDecimal;


public class DoubleToBigDecimalConverter implements Converter<Double, BigDecimal> {

    @Override
    public BigDecimal convert(Double source) {
        return new BigDecimal(source);
    }
}

2. Configure the MongoTemplate to use the custom converters



@Configuration
public class MongoDBConfig  {

   
     //MongoDB properties read from the application.yaml configuration file (to handle different profiles)
    @Value("${spring.data.mongodb.host}")
    private String mongoHost;

    @Value("${spring.data.mongodb.port}")
    private int mongoPort;

    @Value("${spring.data.mongodb.database}")
    private String mongoDatabase;

   
    @Bean
    public MongoTemplate mongoTemplate() throws Exception {

        MongoTemplate mongoTemplate = new MongoTemplate(mongo(), mongoDatabase);
        MappingMongoConverter mongoMapping = (MappingMongoConverter) mongoTemplate.getConverter();
        mongoMapping.setCustomConversions(customConversions()); // tell mongodb to use the custom converters
        mongoMapping.afterPropertiesSet();
        return mongoTemplate;

    }

    /**
    * Configure the MongoDB client
    * 
    **/
    @Bean
    public Mongo mongo() throws Exception {
        return new MongoClient(mongoHost, mongoPort);
    }


   /**
    * Returns the list of custom converters that will be used by the MongoDB template
    * 
    **/
    public CustomConversions customConversions() {
        return new CustomConversions(Arrays.asList(new DoubleToBigDecimalConverter(), new BigDecimalToDoubleConverter()));
    }
}


Please note that this is OK in most cases however please note that in some cases this conversion from BigDecimal to Double may lead to issues; more info : Oracle's official doc on floating point arithmetic

3 comments:

  1. The effectiveness of IEEE Project Domains depends very much on the situation in which they are applied. In order to further improve IEEE Final Year Project Domains practices we need to explicitly describe and utilise our knowledge about software domains of software engineering Final Year Project Domains for CSE technologies. This paper suggests a modelling formalism for supporting systematic reuse of software engineering technologies during planning of software projects and improvement programmes in Project Centers in Chennai for CSE.

    Spring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Spring Framework Corporate TRaining the authors explore the idea of using Java in Big Data platforms.
    Specifically, Spring Framework provides various tasks are geared around preparing data for further analysis and visualization. Spring Training in Chennai

    ReplyDelete
  2. In the newer Spring Data they added simpler way to support BigDecimal:

    @Field(targetType = FieldType.DECIMAL128)
    BigDecimal value;

    https://docs.spring.io/spring-data/data-mongodb/docs/current/reference/html/#mongo.custom-converters

    ReplyDelete

OSX show used ports or listening applications with their PID

On OSX you can display applications listening on a given port using the lsof the commands described below will show listening application...