Mapstruct LocalDateTime to Instant
Asked Answered
S

1

9

I am new in Mapstruct. I have a model object which includes LocalDateTime type field. DTO includes Instant type field. I want to map LocalDateTime type field to Instant type field. I have TimeZone instance of incoming requests.

Manually field setting like that;

set( LocalDateTime.ofInstant(x.getStartDate(), timeZone.toZoneId()) )

How can I map these fields using with Mapstruct?

Seven answered 20/12, 2017 at 7:52 Comment(0)
E
19

You have 2 options to achieve what you are looking for.

First option:

Use the new @Context annotation from 1.2.0.Final for the timeZone property and define your own method that would perform the mapping. Something like:

public interface MyMapper {

    @Mapping(target = "start", source = "startDate")
    Target map(Source source, @Context TimeZone timeZone);

    default LocalDateTime fromInstant(Instant instant, @Context TimeZone timeZone) {
        return instant == null ? null : LocalDateTime.ofInstant(instant, timeZone.toZoneId());
    }
}

MapStruct will then use the provided method to perform mapping between Instant and LocalDateTime.

The second option:

public interface MyMapper {

    @Mapping(target = "start", expression = "java(LocalDateTime.ofInstant(source.getStartDate(), timezone.toZoneId()))")
    Target map(Source source, TimeZone timeZone);
}

My personal option would be to use the first one

Eggshell answered 22/12, 2017 at 22:43 Comment(7)
Thank you Filip, I created a class which includes first option methods (fromInstant and toInstant). I referenced this class to my mapper (@Mapper(uses=LocalTimeMapper.class)). Thanks again.Seven
That's even better as it allows for better usability. For other readers all default methods can be done in another class(es) and be referenced via Mapper#usesEggshell
Absolutely I agree. I have a question about to use Mapstruct mapper as spring bean. When i use componentModel='spring", mapper will be a singleton class.(generated class annotated with @Component). Could there be any performance issue on multi thread requests? To inject mapper as singleton bean or to initialize mapper instance every time ( Mappers.getMapper( XMapper.class ); ), What is your preference ?Seven
Best would be to direct such questions in our chat. In any case using it as a spring bean has no performance hit, using the mappers factory on each request is actually not recommended. Our recommendation, in case you dont want to use dependency injection, is to assign the mapper to some static final field which you would then use everywhere. However, me personally use spring and inject the mappers where they are needed, it is easier for testing purposes as wellEggshell
Ok, i changed my usage to bean injection, thanks Filip for your helpful answers.Seven
I used it for sql timestamp datatype: default LocalDateTime fromTimestamp(Timestamp sqlTimestamp). ThanksMestizo
In version 1.1.0 of mapstruct that @Context is not exists, you can use ZoneId.systemDefault()Shavonda

© 2022 - 2024 — McMap. All rights reserved.