0

I'm trying to make a JMapper convertion from a class Source to Destination, in the source I have a Date and in the destination a LocalDateTime.

Reading the docs of JMapper the logical way is to make a convertion. However the covertion based on the solution from this question doesn't work and I always get null on the destination date.

Now my code

// Source Entity
@Entity
@Table(name = "source")
public class Source {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Long id;    
    @Column
    private String name;
    @Column
    private Date date;

    // ommited getters and setters

}
// Destination entity
public class Destination {
    private Long id;
    private String name;
    private LocalDateTime date;

    // ommited getters and setters
}

// Mapping with API
jMapperAPI = new JMapperAPI();
Conversion dateToLocalDateTime = conversion("dateToLocalDateTime")
                .from("date").to("date").type(JMapConversion.Type.STATIC)
                .body("return java.time.LocalDateTime.ofInstant(${source}.toInstant(), java.time.ZoneId.systemDefault())");
jMapperAPI.add(mappedClass(Destination.class).add(global()
                .excludedAttributes("date"))
                .add(dateToLocalDateTime));

// Converting
mapper = new JMapper<>(Destination.class, Source.class, jMapperAPI);
mapper.getDestination(source);
Community
  • 1
  • 1
Gerson Sosa
  • 366
  • 1
  • 4
  • 12

1 Answers1

2

Finally I found the answer to my on question,

First I was making two mistakes, first I assumed that I had to exclude the field from the global mapping but it doesn't have to be excluded when using convertions.

And second I was assuming that JMapper does an "only one way convertion" for an attribute with the same name in the source and in the destination class "date".

What JMapper really does is that it takes this convertion and validates if it can be applied when converting (in my case) from Date to LocalDateTime and from LocalDateTime to Date.

Given that I had to define two convertions one when converting from Date to LocalDateTime and another when converting from LocalDateTime to Date to achieve this first I changed the name of the destination field, because it seems there is no other way to make difference between with convertion is applied one way or another

This is the code that works:

// Source Entity
@Entity
@Table(name = "source")
public class Source {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Long id;    
    @Column
    private String name;
    @Column
    private Date date;

    // ommited getters and setters

}
// Destination entity
public class Destination {
    private Long id;
    private String name;
    private LocalDateTime localDateTime;

    // ommited getters and setters
}

// Mapping with API
jMapperAPI = new JMapperAPI();

jMapperAPI.add(mappedClass(Destination.class).add(global()
                    .excludedAttributes("localDateTime"))
                    .add(attribute("localDateTime").targetAttributes("date"))
                    .add(conversion("dateToLocalDateTime")
                            .from("date").to("localDateTime")
                            .type(JMapConversion.Type.DYNAMIC)
                            .body("java.time.Instant instant = ${source}.toInstant();" +
                                    "${destination.type} result = java.time.LocalDateTime.ofInstant(instant, java.time.ZoneId.systemDefault());" +
                                    "return result;"))
                    .add(conversion("localDateTimeToDate")
                            .from("localDateTime").to("date")
                            .type(JMapConversion.Type.DYNAMIC)
                            .body("java.time.Instant instant = ${source}.atZone(java.time.ZoneId.systemDefault()).toInstant();" +
                                    "${destination.type} result = java.util.Date.from(instant);" +
                                    "return result;")));
Gerson Sosa
  • 366
  • 1
  • 4
  • 12
  • Why exclude and include the same field? you can reduce the configuration in this way: ...global().targetAttributes("date")... – Alessandro Aug 01 '16 at 15:08
  • @Alessandro Can't find targetAttributes method in global() – Gerson Sosa Aug 02 '16 at 21:18
  • sorry, I've read wrong, in your case you can only write: ... mappedClass(Destination.class).add(global()).add(conversion("dateToLocalDateTime")... There is no reason to exclude from global and include it as normal mapping – Alessandro Aug 03 '16 at 14:13
  • do we need to create JMapperAPI configuration for every pair of classes/Objects we need to map? How can we create a generic method for this? – Nitin Nanda Nov 18 '20 at 17:54