diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ArticleDTO.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ArticleDTO.java new file mode 100644 index 000000000000..b5dc701ce3ab --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ArticleDTO.java @@ -0,0 +1,37 @@ +package com.baeldung.setnullproperty.dto; + +import java.util.Objects; + +public class ArticleDTO extends ReviewableDTO { + + private String title; + + public ArticleDTO(String title) { + this.title = title; + } + + public ArticleDTO() { + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + ArticleDTO that = (ArticleDTO) o; + return Objects.equals(title, that.title); + } + + @Override + public int hashCode() { + return Objects.hashCode(title); + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ReviewableDTO.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ReviewableDTO.java new file mode 100644 index 000000000000..0719a545419e --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/ReviewableDTO.java @@ -0,0 +1,37 @@ +package com.baeldung.setnullproperty.dto; + +import java.util.Objects; + +public class ReviewableDTO { + + private String title; + + public ReviewableDTO() { + } + + public ReviewableDTO(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + ReviewableDTO that = (ReviewableDTO) o; + return Objects.equals(title, that.title); + } + + @Override + public int hashCode() { + return Objects.hashCode(title); + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/WeeklyNewsDTO.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/WeeklyNewsDTO.java new file mode 100644 index 000000000000..537d3c28afd8 --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/dto/WeeklyNewsDTO.java @@ -0,0 +1,42 @@ +package com.baeldung.setnullproperty.dto; + +import java.util.Objects; + +public class WeeklyNewsDTO extends ReviewableDTO { + + private String title; + + public WeeklyNewsDTO() { + } + + public WeeklyNewsDTO(String title1) { + this.title = title1; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + WeeklyNewsDTO that = (WeeklyNewsDTO) o; + return Objects.equals(title, that.title); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), title); + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Article.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Article.java new file mode 100644 index 000000000000..39ee2ee86270 --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Article.java @@ -0,0 +1,38 @@ +package com.baeldung.setnullproperty.entity; + +import java.util.Objects; + +public class Article extends Reviewable { + + private String title; + + public Article(String id, String reviewedBy) { + this.id = id; + this.reviewedBy = reviewedBy; + } + + public Article() { + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Article article = (Article) o; + return Objects.equals(id, article.id) && Objects.equals(reviewedBy, article.reviewedBy); + } + + @Override + public int hashCode() { + return Objects.hash(id, reviewedBy); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Reviewable.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Reviewable.java new file mode 100644 index 000000000000..e7d4cd36e306 --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/Reviewable.java @@ -0,0 +1,54 @@ +package com.baeldung.setnullproperty.entity; + +import java.util.Objects; + +public class Reviewable { + protected String id; + protected String reviewedBy; + protected String title; + + public Reviewable(String reviewedBy) { + this.reviewedBy = reviewedBy; + } + + public Reviewable() { + } + + public String getReviewedBy() { + return reviewedBy; + } + + public void setReviewedBy(String reviewedBy) { + this.reviewedBy = reviewedBy; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Reviewable that = (Reviewable) o; + return Objects.equals(reviewedBy, that.reviewedBy); + } + + @Override + public int hashCode() { + return Objects.hashCode(reviewedBy); + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/WeeklyNews.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/WeeklyNews.java new file mode 100644 index 000000000000..d47f97b5a176 --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/entity/WeeklyNews.java @@ -0,0 +1,27 @@ +package com.baeldung.setnullproperty.entity; + +import java.util.Objects; + +public class WeeklyNews extends Reviewable { + + public WeeklyNews() { + } + + public WeeklyNews(String reviewedBy) { + this.reviewedBy = reviewedBy; + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + WeeklyNews that = (WeeklyNews) o; + return Objects.equals(reviewedBy, that.reviewedBy); + } + + @Override + public int hashCode() { + return Objects.hashCode(reviewedBy); + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ArticleMapper.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ArticleMapper.java new file mode 100644 index 000000000000..44549c0198a0 --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ArticleMapper.java @@ -0,0 +1,52 @@ +package com.baeldung.setnullproperty.mapper; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Named; + +import com.baeldung.setnullproperty.dto.ArticleDTO; +import com.baeldung.setnullproperty.entity.Article; + +@Mapper(uses = ReviewableMapper.class) +public interface ArticleMapper { + + @Mapping(target = "title", source = "dto.title") + @Mapping(target = "id", source = "persisted.id") + @Mapping(target = "reviewedBy", expression = "java(null)") + Article toArticleUsingExpression(ArticleDTO dto, Article persisted); + + @Mapping(target = "title", source = "dto.title") + @Mapping(target = "id", source = "persisted.id") + @Mapping(target = "reviewedBy", expression = "java(getDefaultReviewStatus())") + Article toArticleUsingExpressionMethod(ArticleDTO dto, Article persisted); + + default String getDefaultReviewStatus() { + return null; + } + + @Mapping(target = "title", source = "dto.title") + @Mapping(target = "id", source = "persisted.id") + @Mapping(target = "reviewedBy", ignore = true) + Article toArticleUsingIgnore(ArticleDTO dto, Article persisted); + + @AfterMapping + default void setNullReviewedBy(@MappingTarget Article article) { + article.setReviewedBy(null); + } + + @Mapping(target = "title", source = "dto.title") + @Mapping(target = "id", source = "persisted.id") + Article toArticleUsingAfterMapping(ArticleDTO dto, Article persisted); + + @Mapping(target = "title", source = "dto.title") + @Mapping(target = "id", source = "persisted.id") + @Mapping(target = "reviewedBy", qualifiedByName = "toNull") + Article toArticleUsingQualifiedBy(ArticleDTO dto, Article persisted); + + @Named("toNull") + default String mapToNull(String property) { + return null; + } +} diff --git a/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ReviewableMapper.java b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ReviewableMapper.java new file mode 100644 index 000000000000..5f21db07fb4b --- /dev/null +++ b/mapstruct-3/src/main/java/com/baeldung/setnullproperty/mapper/ReviewableMapper.java @@ -0,0 +1,22 @@ +package com.baeldung.setnullproperty.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SubclassMapping; + +import com.baeldung.setnullproperty.dto.ArticleDTO; +import com.baeldung.setnullproperty.dto.ReviewableDTO; +import com.baeldung.setnullproperty.dto.WeeklyNewsDTO; +import com.baeldung.setnullproperty.entity.Article; +import com.baeldung.setnullproperty.entity.Reviewable; +import com.baeldung.setnullproperty.entity.WeeklyNews; + +@Mapper +public interface ReviewableMapper { + + @SubclassMapping(source = ArticleDTO.class, target = Article.class) + @SubclassMapping(source = WeeklyNewsDTO.class, target = WeeklyNews.class) + @Mapping(target = "reviewedBy", expression = "java(null)") + Reviewable toReviewable(ReviewableDTO dto); + +} diff --git a/mapstruct-3/src/test/java/com/baeldung/setnullproperty/mapper/ArticleMapperUnitTest.java b/mapstruct-3/src/test/java/com/baeldung/setnullproperty/mapper/ArticleMapperUnitTest.java new file mode 100644 index 000000000000..b8fc78c035cb --- /dev/null +++ b/mapstruct-3/src/test/java/com/baeldung/setnullproperty/mapper/ArticleMapperUnitTest.java @@ -0,0 +1,78 @@ +package com.baeldung.setnullproperty.mapper; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import com.baeldung.setnullproperty.dto.ArticleDTO; +import com.baeldung.setnullproperty.dto.WeeklyNewsDTO; +import com.baeldung.setnullproperty.entity.Article; +import com.baeldung.setnullproperty.entity.Reviewable; +import com.baeldung.setnullproperty.entity.WeeklyNews; + +class ArticleMapperUnitTest { + + private ArticleMapper articleMapper; + private ReviewableMapper reviewableMapper; + + @BeforeEach + void setUp() { + articleMapper = Mappers.getMapper(ArticleMapper.class); + reviewableMapper = Mappers.getMapper(ReviewableMapper.class); + } + + @Test + void givenArticleDTO_whenToArticleUsingExpression_thenReturnsArticleWithNullStatus() { + Article oldArticle1 = new Article("ID-1", "John Doe"); + Article oldArticle2 = new Article("ID-2", "John Doe"); + + Article result1 = articleMapper.toArticleUsingExpression(new ArticleDTO("Updated article 1 title"), oldArticle1); + Article result2 = articleMapper.toArticleUsingExpressionMethod(new ArticleDTO("Updated article 2 title"), oldArticle2); + + assertThat(result1.getReviewedBy()).isNull(); + assertThat(result2.getReviewedBy()).isNull(); + assertThat(result1.getTitle()).isEqualTo("Updated article 1 title"); + assertThat(result2.getTitle()).isEqualTo("Updated article 2 title"); + } + + @Test + void givenArticleDTO_whenToArticleUsingIgnore_thenReturnsArticleWithNullStatus() { + Article oldArticle1 = new Article("ID-1", "John Doe"); + + Article result1 = articleMapper.toArticleUsingIgnore(new ArticleDTO("Updated article 1 title"), oldArticle1); + + assertThat(result1.getReviewedBy()).isNull(); + assertThat(result1.getTitle()).isEqualTo("Updated article 1 title"); + } + + @Test + void givenArticleDTO_whenToArticleUsingAfterMapping_thenReturnsArticleWithNullStatus() { + Article oldArticle1 = new Article("ID-1", "John Doe"); + + Article result1 = articleMapper.toArticleUsingAfterMapping(new ArticleDTO("Updated article 1 title"), oldArticle1); + + assertThat(result1.getReviewedBy()).isNull(); + assertThat(result1.getTitle()).isEqualTo("Updated article 1 title"); + } + + @Test + void givenArticleDTO_whenToArticleUsingQualifiedBy_thenReturnsArticleWithNullStatus() { + Article result1 = articleMapper.toArticleUsingQualifiedBy(new ArticleDTO("Updated article 1 title"), new Article("ID-1", "John Doe")); + + assertThat(result1.getReviewedBy()).isNull(); + assertThat(result1.getTitle()).isEqualTo("Updated article 1 title"); + } + + @Test + void givenArticleDTO_whenToReviewableUsingMapper_thenReturnsArticleWithNullStatus() { + Reviewable result1 = reviewableMapper.toReviewable(new ArticleDTO("Updated article 1 title")); + Reviewable result2 = reviewableMapper.toReviewable(new WeeklyNewsDTO()); + + assertThat(result1).isInstanceOf(Article.class); + assertThat(result2).isInstanceOf(WeeklyNews.class); + assertThat(result1.getReviewedBy()).isNull(); + assertThat(result2.getReviewedBy()).isNull(); + } +} \ No newline at end of file