Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modelmapper to convert from String to LocalDate

My DTO is having date field in String format. My entity is having date as LocalDate. Currently I am skipping it from map and then later manually explicitly setting it (String to Date and vis-versa).

is it possible to convert it automatically? I tried Converter inside spring bean but it gives me lot of compile errors (type Converter does not take parameters, does not override convert method - also lot of error for convert() as well).

@Bean
public ModelMapper studentModelMapper() {
....    
    Converter<String, LocalDate> toStringDate = new AbstractConverter<String, LocalDate>() {
        protected String convert(String source) {
            return source == null ? null : new LocalDate(source);
        }
    };
....
}

I am not very familiar with modelmapper. Any help is greatly appreciated.

As suggested I tried with LocalDate for DTO but the problem is when I send this entity at front (REST call) I get following JSON.

"dateOfBirth": {
   "year": 1972,
   "month": "JANUARY",
   "monthValue": 1,
   "dayOfMonth": 4,
   "dayOfWeek": "TUESDAY",
   "era": "CE",
   "dayOfYear": 4,
   "leapYear": true,
   "chronology": {
      "id": "ISO",
      "calendarType": "iso8601"
   }
}

My front end developer need "YYYY-MM-DD".

like image 971
user2869612 Avatar asked Sep 12 '16 16:09

user2869612


3 Answers

If you want to convert to LocalDate you need to create a Provider otherwise ModelMappercannot instantiate LocalDate because it doesn't have a public default constructor.

Use this configuration and it will work:

 ModelMapper modelmapper = new ModelMapper();

    Provider<LocalDate> localDateProvider = new AbstractProvider<LocalDate>() {
        @Override
        public LocalDate get() {
            return LocalDate.now();
        }
    };

    Converter<String, LocalDate> toStringDate = new AbstractConverter<String, LocalDate>() {
        @Override
        protected LocalDate convert(String source) {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate localDate = LocalDate.parse(source, format);
            return localDate;
        }
    };


    modelmapper.createTypeMap(String.class, LocalDate.class);
    modelmapper.addConverter(toStringDate);
    modelmapper.getTypeMap(String.class, LocalDate.class).setProvider(localDateProvider);

Test output:

 String dateTest = "2000-09-27";
 LocalDate dateConverted = modelmapper.map(dateTest, LocalDate.class);

 System.out.println(dateConverted.toString()); //Output = 2000-09-27
like image 140
Pau Avatar answered Oct 23 '22 20:10

Pau


I also use ModelMapper 2.3.5 for my project and had a similar issue. The use of the ModelMapper related project https://github.com/modelmapper/modelmapper-module-java8/ helped me a lot.

It provides two modules that one can add to ModelMapper configuration by providing the following maven dependencies to your project :

<!-- https://mvnrepository.com/artifact/com.github.chhsiao90/modelmapper-module-java8-datatypes -->
<dependency>
    <groupId>com.github.chhsiao90</groupId>
    <artifactId>modelmapper-module-java8-datatypes</artifactId>
    <version>1.1.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.github.chhsiao90/modelmapper-module-jsr310 -->
<dependency>
    <groupId>com.github.chhsiao90</groupId>
    <artifactId>modelmapper-module-jsr310</artifactId>
    <version>1.1.0</version>
</dependency>

Then the ModelMapper configuration should add

modelMapper.registerModule(new Jsr310Module());
modelMapper.registerModule(new Jdk8Module());

Hope this can help

like image 37
Pierre-Emmanuel JEAN Avatar answered Oct 23 '22 20:10

Pierre-Emmanuel JEAN


I am currently using ModelMapper 2.3.5 and the accepted solution does not work with me when I do ModelMapper.validate() for my mapping. See my related question.

I managed to get also validation working - surprisingly - by removing provider totally so only converter is used. So like:

modelmapper.addConverter(toStringDate);
modelmapper.getTypeMap(String.class, LocalDate.class); // no provider, maps ok with me still
modelmapper.validate();
like image 40
pirho Avatar answered Oct 23 '22 21:10

pirho