Home > database >  Spring boot: Custom mapping between DTO and Entity using ModelMapper
Spring boot: Custom mapping between DTO and Entity using ModelMapper

Time:11-18

I would like to map my DTO (CreateOrUpdatePostRequest) to my entity Post.

But I'm not sure how to go about it since my entity has relationships like this:

@Entity
@Table(name = "POSTS")
@Data
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id")
    private int id;

    private String title;

    private String description;

    @Temporal(TemporalType.DATE)
    @Column(name = "expire_at")
    private Calendar expireAt;

    @ManyToOne
    @JoinColumn(name = "CATEGORY_ID")
    private Category category;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "TAG_POST", joinColumns = { 
            @JoinColumn(name = "post_id", nullable = false, updatable = false) }, 
            inverseJoinColumns = { @JoinColumn(name = "tag_id", 
                    nullable = false, updatable = false) })
    private Set<Tag> tags = new HashSet<Tag>(0);
}

A post can have one category and several tags.

And here is my DTO :

@Data
public class CreateOrUpdatePostRequest {
    @NotNull
    @Size(min = 10, max = 30)
    private Sting title;

    @NotNull
    @Size(min = 50, max = 600)
    private String description

    @NotNull
    @ValidDateString
    private String expireAt;

    @NotNull
    private Category category;

    @NotNull
    private List<TagDTO> tags;

    public List<Integer> getTagIds() {
        return this.getTags().stream().map(TagDTO::getId).collect(Collectors.toList());
    }
}

Problem: My problem is that I have to apply a particular mapping logic for some properties to make sure that the tags are valid for example:

post.setTags(tagService.findAllByIds(request.getTagIds()));
  1. So I guess the mapping should be done in my PostService knowing that I have to access the tagService? What I mean is that I can't really create a toEntity method in my CreateOrUpdateRequest.

  2. Is there a way to leave the default ModelMapper behavior for all properties, but specify specific behavior using an external service for certain properties?

  3. How to proceed if for example my DTO has a DTO inside that needs the same behavior described above, for example in a TagDTO?

CodePudding user response:

I am not sure whether you have already gone through MapStruct thing, but you can look at it here in detail.

https://medium.com/uphill-engineering-design/deep-dive-into-mapstruct-spring-7ddd8dac3d6d

CodePudding user response:

This is borderline opinion-based, but still here is my take on this:

  1. I guess that your PostService is a Spring-managed Bean (possibly annotated with @Service), so I would say the mapping should be done there, using TagService to get the Tags.
  2. I am not a big fan of any mapper library, simply because once using Spring you have already enough magic going around in your code. Having said that, I much more prefer to be explicit and map the models on my own. You have full flexibility while doing so.
  3. I would say that TagDto should be mapped by the TagService.
  • Related