diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 87c782b044..e6866b5a8f 100644
--- a/spring-boot/pom.xml
+++ b/spring-boot/pom.xml
@@ -162,6 +162,12 @@
javax.validation
validation-api
+
+
+ org.modelmapper
+ modelmapper
+ ${modelmapper.version}
+
@@ -259,6 +265,7 @@
5.2.4
18.0
2.2.4
+ 2.3.2
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java b/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java
new file mode 100644
index 0000000000..7684c43648
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/PostApplication.java
@@ -0,0 +1,20 @@
+package com.baeldung.modelmapper;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class PostApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PostApplication.class, args);
+ }
+
+ @Bean
+ public ModelMapper modelMapper() {
+ return new ModelMapper();
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java b/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java
new file mode 100644
index 0000000000..c0cbca5220
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/controller/PostRestController.java
@@ -0,0 +1,91 @@
+package com.baeldung.modelmapper.controller;
+
+import java.text.ParseException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import com.baeldung.modelmapper.dto.PostDto;
+import com.baeldung.modelmapper.model.Post;
+import com.baeldung.modelmapper.service.IPostService;
+import com.baeldung.modelmapper.service.IUserService;
+
+@Controller
+public class PostRestController {
+
+ @Autowired
+ private IPostService postService;
+
+ @Autowired
+ private IUserService userService;
+
+ @Autowired
+ private ModelMapper modelMapper;
+
+ @RequestMapping(method = RequestMethod.GET)
+ @ResponseBody
+ public List getPosts(
+ @PathVariable("page") int page,
+ @PathVariable("size") int size,
+ @PathVariable("sortDir") String sortDir,
+ @PathVariable("sort") String sort) {
+
+ List posts = postService.getPostsList(page, size, sortDir, sort);
+ return posts.stream()
+ .map(post -> convertToDto(post))
+ .collect(Collectors.toList());
+ }
+
+ @RequestMapping(method = RequestMethod.POST)
+ @ResponseStatus(HttpStatus.CREATED)
+ @ResponseBody
+ public PostDto createPost(@RequestBody PostDto postDto) throws ParseException {
+ Post post = convertToEntity(postDto);
+ Post postCreated = postService.createPost(post);
+ return convertToDto(postCreated);
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ @ResponseBody
+ public PostDto getPost(@PathVariable("id") Long id) {
+ return convertToDto(postService.getPostById(id));
+ }
+
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ @ResponseStatus(HttpStatus.OK)
+ public void updatePost(@RequestBody PostDto postDto) throws ParseException {
+ Post post = convertToEntity(postDto);
+ postService.updatePost(post);
+ }
+
+
+ private PostDto convertToDto(Post post) {
+ PostDto postDto = modelMapper.map(post, PostDto.class);
+ postDto.setSubmissionDate(post.getSubmissionDate(),
+ userService.getCurrentUser().getPreference().getTimezone());
+ return postDto;
+ }
+
+ private Post convertToEntity(PostDto postDto) throws ParseException {
+ Post post = modelMapper.map(postDto, Post.class);
+ post.setSubmissionDate(postDto.getSubmissionDateConverted(
+ userService.getCurrentUser().getPreference().getTimezone()));
+
+ if (postDto.getId() != null) {
+ Post oldPost = postService.getPostById(postDto.getId());
+ post.setRedditID(oldPost.getRedditID());
+ post.setSent(oldPost.isSent());
+ }
+ return post;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java
new file mode 100644
index 0000000000..6fe2b23888
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/PostDto.java
@@ -0,0 +1,71 @@
+package com.baeldung.modelmapper.dto;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class PostDto {
+
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+
+ private Long id;
+
+ private String title;
+
+ private String url;
+
+ private String date;
+
+ private UserDto user;
+
+ public Date getSubmissionDateConverted(String timezone) throws ParseException {
+ dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));
+ return dateFormat.parse(this.date);
+ }
+
+ public void setSubmissionDate(Date date, String timezone) {
+ dateFormat.setTimeZone(TimeZone.getTimeZone(timezone));
+ this.date = dateFormat.format(date);
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public UserDto getUser() {
+ return user;
+ }
+
+ public void setUser(UserDto user) {
+ this.user = user;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java
new file mode 100644
index 0000000000..23110ecbaa
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/dto/UserDto.java
@@ -0,0 +1,14 @@
+package com.baeldung.modelmapper.dto;
+
+public class UserDto {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java
new file mode 100644
index 0000000000..be65ce34a2
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Post.java
@@ -0,0 +1,98 @@
+package com.baeldung.modelmapper.model;
+
+import java.util.Date;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Post {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String title;
+
+ private String url;
+
+ private String date;
+
+ private String redditID;
+
+ private Date submissionDate;
+
+ private boolean sent;
+
+ private String userName;
+
+ public Post() {
+
+ }
+
+ public boolean isSent() {
+ return sent;
+ }
+
+ public void setSent(boolean sent) {
+ this.sent = sent;
+ }
+
+ public String getRedditID() {
+ return redditID;
+ }
+
+ public void setRedditID(String redditID) {
+ this.redditID = redditID;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public Date getSubmissionDate() {
+ return submissionDate;
+ }
+
+ public void setSubmissionDate(Date submissionDate) {
+ this.submissionDate = submissionDate;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java
new file mode 100644
index 0000000000..0ab5b1eddf
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/Preference.java
@@ -0,0 +1,32 @@
+package com.baeldung.modelmapper.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Preference {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String timezone;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getTimezone() {
+ return timezone;
+ }
+
+ public void setTimezone(String timezone) {
+ this.timezone = timezone;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java b/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java
new file mode 100644
index 0000000000..a458b26f4a
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/model/User.java
@@ -0,0 +1,44 @@
+package com.baeldung.modelmapper.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String name;
+
+ @OneToOne
+ Preference preference;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Preference getPreference() {
+ return preference;
+ }
+
+ public void setPreference(Preference preference) {
+ this.preference = preference;
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java b/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java
new file mode 100644
index 0000000000..fc3f5733c3
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/repository/PostRepository.java
@@ -0,0 +1,21 @@
+package com.baeldung.modelmapper.repository;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
+
+import com.baeldung.modelmapper.model.Post;
+import com.baeldung.modelmapper.model.User;
+
+public interface PostRepository extends JpaRepository, PagingAndSortingRepository {
+
+ @Query("select u from Post u where u.userName=:userName")
+ Page findByUser(@Param("userName") String userName, Pageable pageReq);
+
+ default Page findByUser(User user, Pageable pageReq) {
+ return findByUser(user.getName(), pageReq);
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java
new file mode 100644
index 0000000000..0182a0da41
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IPostService.java
@@ -0,0 +1,17 @@
+package com.baeldung.modelmapper.service;
+
+import java.util.List;
+
+import com.baeldung.modelmapper.model.Post;
+
+public interface IPostService {
+
+ List getPostsList(int page, int size, String sortDir, String sort);
+
+ void updatePost(Post post);
+
+ Post createPost(Post post);
+
+ Post getPostById(Long id);
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java
new file mode 100644
index 0000000000..79934114c1
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/IUserService.java
@@ -0,0 +1,9 @@
+package com.baeldung.modelmapper.service;
+
+import com.baeldung.modelmapper.model.User;
+
+public interface IUserService {
+
+ User getCurrentUser();
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java
new file mode 100644
index 0000000000..5980c30837
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/PostService.java
@@ -0,0 +1,47 @@
+package com.baeldung.modelmapper.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.modelmapper.model.Post;
+import com.baeldung.modelmapper.repository.PostRepository;
+
+@Service
+public class PostService implements IPostService {
+
+ @Autowired
+ private PostRepository postRepository;
+
+ @Autowired
+ private IUserService userService;
+
+ @Override
+ public List getPostsList(int page, int size, String sortDir, String sort) {
+
+ PageRequest pageReq
+ = PageRequest.of(page, size, Sort.Direction.fromString(sortDir), sort);
+
+ Page posts = postRepository.findByUser(userService.getCurrentUser(), pageReq);
+ return posts.getContent();
+ }
+
+ @Override
+ public void updatePost(Post post) {
+ postRepository.save(post);
+ }
+
+ @Override
+ public Post createPost(Post post) {
+ return postRepository.save(post);
+ }
+
+ @Override
+ public Post getPostById(Long id) {
+ return postRepository.getOne(id);
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java b/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java
new file mode 100644
index 0000000000..e445f836a4
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/modelmapper/service/UserService.java
@@ -0,0 +1,25 @@
+package com.baeldung.modelmapper.service;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.modelmapper.model.Preference;
+import com.baeldung.modelmapper.model.User;
+
+@Service
+public class UserService implements IUserService {
+
+ @Override
+ public User getCurrentUser() {
+
+ Preference preference = new Preference();
+ preference.setId(1L);
+ preference.setTimezone("Asia/Calcutta");
+
+ User user = new User();
+ user.setId(1L);
+ user.setName("Micheal");
+ user.setPreference(preference);
+
+ return user;
+ }
+}
\ No newline at end of file
diff --git a/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java b/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java
new file mode 100644
index 0000000000..34ec4db783
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/modelmapper/PostDtoUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.modelmapper;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+import org.junit.Test;
+import org.modelmapper.ModelMapper;
+
+import com.baeldung.modelmapper.dto.PostDto;
+import com.baeldung.modelmapper.model.Post;
+
+public class PostDtoUnitTest {
+
+ private ModelMapper modelMapper = new ModelMapper();
+
+ @Test
+ public void whenConvertPostEntityToPostDto_thenCorrect() {
+ Post post = new Post();
+ post.setId(Long.valueOf(1));
+ post.setTitle(randomAlphabetic(6));
+ post.setUrl("www.test.com");
+
+ PostDto postDto = modelMapper.map(post, PostDto.class);
+ assertEquals(post.getId(), postDto.getId());
+ assertEquals(post.getTitle(), postDto.getTitle());
+ assertEquals(post.getUrl(), postDto.getUrl());
+ }
+
+ @Test
+ public void whenConvertPostDtoToPostEntity_thenCorrect() {
+ PostDto postDto = new PostDto();
+ postDto.setId(Long.valueOf(1));
+ postDto.setTitle(randomAlphabetic(6));
+ postDto.setUrl("www.test.com");
+
+ Post post = modelMapper.map(postDto, Post.class);
+ assertEquals(postDto.getId(), post.getId());
+ assertEquals(postDto.getTitle(), post.getTitle());
+ assertEquals(postDto.getUrl(), post.getUrl());
+ }
+}
\ No newline at end of file