Skip to content

Commit f6a0a01

Browse files
BAEL-9152: Set the Null Value for a Target Property in Mapstruct (#18869)
* wraps up mapping using expression * final version
1 parent 84b0c06 commit f6a0a01

File tree

9 files changed

+387
-0
lines changed

9 files changed

+387
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.baeldung.setnullproperty.dto;
2+
3+
import java.util.Objects;
4+
5+
public class ArticleDTO extends ReviewableDTO {
6+
7+
private String title;
8+
9+
public ArticleDTO(String title) {
10+
this.title = title;
11+
}
12+
13+
public ArticleDTO() {
14+
}
15+
16+
public String getTitle() {
17+
return title;
18+
}
19+
20+
public void setTitle(String title) {
21+
this.title = title;
22+
}
23+
24+
@Override
25+
public boolean equals(Object o) {
26+
if (o == null || getClass() != o.getClass()) {
27+
return false;
28+
}
29+
ArticleDTO that = (ArticleDTO) o;
30+
return Objects.equals(title, that.title);
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return Objects.hashCode(title);
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.baeldung.setnullproperty.dto;
2+
3+
import java.util.Objects;
4+
5+
public class ReviewableDTO {
6+
7+
private String title;
8+
9+
public ReviewableDTO() {
10+
}
11+
12+
public ReviewableDTO(String title) {
13+
this.title = title;
14+
}
15+
16+
public String getTitle() {
17+
return title;
18+
}
19+
20+
public void setTitle(String title) {
21+
this.title = title;
22+
}
23+
24+
@Override
25+
public boolean equals(Object o) {
26+
if (o == null || getClass() != o.getClass()) {
27+
return false;
28+
}
29+
ReviewableDTO that = (ReviewableDTO) o;
30+
return Objects.equals(title, that.title);
31+
}
32+
33+
@Override
34+
public int hashCode() {
35+
return Objects.hashCode(title);
36+
}
37+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.baeldung.setnullproperty.dto;
2+
3+
import java.util.Objects;
4+
5+
public class WeeklyNewsDTO extends ReviewableDTO {
6+
7+
private String title;
8+
9+
public WeeklyNewsDTO() {
10+
}
11+
12+
public WeeklyNewsDTO(String title1) {
13+
this.title = title1;
14+
}
15+
16+
@Override
17+
public String getTitle() {
18+
return title;
19+
}
20+
21+
@Override
22+
public void setTitle(String title) {
23+
this.title = title;
24+
}
25+
26+
@Override
27+
public boolean equals(Object o) {
28+
if (o == null || getClass() != o.getClass()) {
29+
return false;
30+
}
31+
if (!super.equals(o)) {
32+
return false;
33+
}
34+
WeeklyNewsDTO that = (WeeklyNewsDTO) o;
35+
return Objects.equals(title, that.title);
36+
}
37+
38+
@Override
39+
public int hashCode() {
40+
return Objects.hash(super.hashCode(), title);
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.baeldung.setnullproperty.entity;
2+
3+
import java.util.Objects;
4+
5+
public class Article extends Reviewable {
6+
7+
private String title;
8+
9+
public Article(String id, String reviewedBy) {
10+
this.id = id;
11+
this.reviewedBy = reviewedBy;
12+
}
13+
14+
public Article() {
15+
}
16+
17+
@Override
18+
public boolean equals(Object o) {
19+
if (o == null || getClass() != o.getClass()) {
20+
return false;
21+
}
22+
Article article = (Article) o;
23+
return Objects.equals(id, article.id) && Objects.equals(reviewedBy, article.reviewedBy);
24+
}
25+
26+
@Override
27+
public int hashCode() {
28+
return Objects.hash(id, reviewedBy);
29+
}
30+
31+
public String getTitle() {
32+
return title;
33+
}
34+
35+
public void setTitle(String title) {
36+
this.title = title;
37+
}
38+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.baeldung.setnullproperty.entity;
2+
3+
import java.util.Objects;
4+
5+
public class Reviewable {
6+
protected String id;
7+
protected String reviewedBy;
8+
protected String title;
9+
10+
public Reviewable(String reviewedBy) {
11+
this.reviewedBy = reviewedBy;
12+
}
13+
14+
public Reviewable() {
15+
}
16+
17+
public String getReviewedBy() {
18+
return reviewedBy;
19+
}
20+
21+
public void setReviewedBy(String reviewedBy) {
22+
this.reviewedBy = reviewedBy;
23+
}
24+
25+
public String getId() {
26+
return id;
27+
}
28+
29+
public void setId(String id) {
30+
this.id = id;
31+
}
32+
33+
public String getTitle() {
34+
return title;
35+
}
36+
37+
public void setTitle(String title) {
38+
this.title = title;
39+
}
40+
41+
@Override
42+
public boolean equals(Object o) {
43+
if (o == null || getClass() != o.getClass()) {
44+
return false;
45+
}
46+
Reviewable that = (Reviewable) o;
47+
return Objects.equals(reviewedBy, that.reviewedBy);
48+
}
49+
50+
@Override
51+
public int hashCode() {
52+
return Objects.hashCode(reviewedBy);
53+
}
54+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.baeldung.setnullproperty.entity;
2+
3+
import java.util.Objects;
4+
5+
public class WeeklyNews extends Reviewable {
6+
7+
public WeeklyNews() {
8+
}
9+
10+
public WeeklyNews(String reviewedBy) {
11+
this.reviewedBy = reviewedBy;
12+
}
13+
14+
@Override
15+
public boolean equals(Object o) {
16+
if (o == null || getClass() != o.getClass()) {
17+
return false;
18+
}
19+
WeeklyNews that = (WeeklyNews) o;
20+
return Objects.equals(reviewedBy, that.reviewedBy);
21+
}
22+
23+
@Override
24+
public int hashCode() {
25+
return Objects.hashCode(reviewedBy);
26+
}
27+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.baeldung.setnullproperty.mapper;
2+
3+
import org.mapstruct.AfterMapping;
4+
import org.mapstruct.Mapper;
5+
import org.mapstruct.Mapping;
6+
import org.mapstruct.MappingTarget;
7+
import org.mapstruct.Named;
8+
9+
import com.baeldung.setnullproperty.dto.ArticleDTO;
10+
import com.baeldung.setnullproperty.entity.Article;
11+
12+
@Mapper(uses = ReviewableMapper.class)
13+
public interface ArticleMapper {
14+
15+
@Mapping(target = "title", source = "dto.title")
16+
@Mapping(target = "id", source = "persisted.id")
17+
@Mapping(target = "reviewedBy", expression = "java(null)")
18+
Article toArticleUsingExpression(ArticleDTO dto, Article persisted);
19+
20+
@Mapping(target = "title", source = "dto.title")
21+
@Mapping(target = "id", source = "persisted.id")
22+
@Mapping(target = "reviewedBy", expression = "java(getDefaultReviewStatus())")
23+
Article toArticleUsingExpressionMethod(ArticleDTO dto, Article persisted);
24+
25+
default String getDefaultReviewStatus() {
26+
return null;
27+
}
28+
29+
@Mapping(target = "title", source = "dto.title")
30+
@Mapping(target = "id", source = "persisted.id")
31+
@Mapping(target = "reviewedBy", ignore = true)
32+
Article toArticleUsingIgnore(ArticleDTO dto, Article persisted);
33+
34+
@AfterMapping
35+
default void setNullReviewedBy(@MappingTarget Article article) {
36+
article.setReviewedBy(null);
37+
}
38+
39+
@Mapping(target = "title", source = "dto.title")
40+
@Mapping(target = "id", source = "persisted.id")
41+
Article toArticleUsingAfterMapping(ArticleDTO dto, Article persisted);
42+
43+
@Mapping(target = "title", source = "dto.title")
44+
@Mapping(target = "id", source = "persisted.id")
45+
@Mapping(target = "reviewedBy", qualifiedByName = "toNull")
46+
Article toArticleUsingQualifiedBy(ArticleDTO dto, Article persisted);
47+
48+
@Named("toNull")
49+
default String mapToNull(String property) {
50+
return null;
51+
}
52+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.baeldung.setnullproperty.mapper;
2+
3+
import org.mapstruct.Mapper;
4+
import org.mapstruct.Mapping;
5+
import org.mapstruct.SubclassMapping;
6+
7+
import com.baeldung.setnullproperty.dto.ArticleDTO;
8+
import com.baeldung.setnullproperty.dto.ReviewableDTO;
9+
import com.baeldung.setnullproperty.dto.WeeklyNewsDTO;
10+
import com.baeldung.setnullproperty.entity.Article;
11+
import com.baeldung.setnullproperty.entity.Reviewable;
12+
import com.baeldung.setnullproperty.entity.WeeklyNews;
13+
14+
@Mapper
15+
public interface ReviewableMapper {
16+
17+
@SubclassMapping(source = ArticleDTO.class, target = Article.class)
18+
@SubclassMapping(source = WeeklyNewsDTO.class, target = WeeklyNews.class)
19+
@Mapping(target = "reviewedBy", expression = "java(null)")
20+
Reviewable toReviewable(ReviewableDTO dto);
21+
22+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.baeldung.setnullproperty.mapper;
2+
3+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
4+
5+
import org.junit.jupiter.api.BeforeEach;
6+
import org.junit.jupiter.api.Test;
7+
import org.mapstruct.factory.Mappers;
8+
9+
import com.baeldung.setnullproperty.dto.ArticleDTO;
10+
import com.baeldung.setnullproperty.dto.WeeklyNewsDTO;
11+
import com.baeldung.setnullproperty.entity.Article;
12+
import com.baeldung.setnullproperty.entity.Reviewable;
13+
import com.baeldung.setnullproperty.entity.WeeklyNews;
14+
15+
class ArticleMapperUnitTest {
16+
17+
private ArticleMapper articleMapper;
18+
private ReviewableMapper reviewableMapper;
19+
20+
@BeforeEach
21+
void setUp() {
22+
articleMapper = Mappers.getMapper(ArticleMapper.class);
23+
reviewableMapper = Mappers.getMapper(ReviewableMapper.class);
24+
}
25+
26+
@Test
27+
void givenArticleDTO_whenToArticleUsingExpression_thenReturnsArticleWithNullStatus() {
28+
Article oldArticle1 = new Article("ID-1", "John Doe");
29+
Article oldArticle2 = new Article("ID-2", "John Doe");
30+
31+
Article result1 = articleMapper.toArticleUsingExpression(new ArticleDTO("Updated article 1 title"), oldArticle1);
32+
Article result2 = articleMapper.toArticleUsingExpressionMethod(new ArticleDTO("Updated article 2 title"), oldArticle2);
33+
34+
assertThat(result1.getReviewedBy()).isNull();
35+
assertThat(result2.getReviewedBy()).isNull();
36+
assertThat(result1.getTitle()).isEqualTo("Updated article 1 title");
37+
assertThat(result2.getTitle()).isEqualTo("Updated article 2 title");
38+
}
39+
40+
@Test
41+
void givenArticleDTO_whenToArticleUsingIgnore_thenReturnsArticleWithNullStatus() {
42+
Article oldArticle1 = new Article("ID-1", "John Doe");
43+
44+
Article result1 = articleMapper.toArticleUsingIgnore(new ArticleDTO("Updated article 1 title"), oldArticle1);
45+
46+
assertThat(result1.getReviewedBy()).isNull();
47+
assertThat(result1.getTitle()).isEqualTo("Updated article 1 title");
48+
}
49+
50+
@Test
51+
void givenArticleDTO_whenToArticleUsingAfterMapping_thenReturnsArticleWithNullStatus() {
52+
Article oldArticle1 = new Article("ID-1", "John Doe");
53+
54+
Article result1 = articleMapper.toArticleUsingAfterMapping(new ArticleDTO("Updated article 1 title"), oldArticle1);
55+
56+
assertThat(result1.getReviewedBy()).isNull();
57+
assertThat(result1.getTitle()).isEqualTo("Updated article 1 title");
58+
}
59+
60+
@Test
61+
void givenArticleDTO_whenToArticleUsingQualifiedBy_thenReturnsArticleWithNullStatus() {
62+
Article result1 = articleMapper.toArticleUsingQualifiedBy(new ArticleDTO("Updated article 1 title"), new Article("ID-1", "John Doe"));
63+
64+
assertThat(result1.getReviewedBy()).isNull();
65+
assertThat(result1.getTitle()).isEqualTo("Updated article 1 title");
66+
}
67+
68+
@Test
69+
void givenArticleDTO_whenToReviewableUsingMapper_thenReturnsArticleWithNullStatus() {
70+
Reviewable result1 = reviewableMapper.toReviewable(new ArticleDTO("Updated article 1 title"));
71+
Reviewable result2 = reviewableMapper.toReviewable(new WeeklyNewsDTO());
72+
73+
assertThat(result1).isInstanceOf(Article.class);
74+
assertThat(result2).isInstanceOf(WeeklyNews.class);
75+
assertThat(result1.getReviewedBy()).isNull();
76+
assertThat(result2.getReviewedBy()).isNull();
77+
}
78+
}

0 commit comments

Comments
 (0)