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()));
So I guess the mapping should be done in my
PostService
knowing that I have to access thetagService
? What I mean is that I can't really create atoEntity
method in myCreateOrUpdateRequest
.Is there a way to leave the default ModelMapper behavior for all properties, but specify specific behavior using an external service for certain properties?
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:
- I guess that your
PostService
is a Spring-managed Bean (possibly annotated with@Service
), so I would say the mapping should be done there, usingTagService
to get theTag
s. - 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.
- I would say that
TagDto
should be mapped by theTagService
.