title: Spring boot Restful API: DTO with relationships convert to entity using ModelMapper?
body: <p>I'm now confused about how to do a CRUD in a Rest API with Spring.</p>
  <p>Let me explain, I have two routes to POST and PUT an entity. I created two DTOs <code>createPostRequest</code> and <code>updatePostRequest</code> for this. Because when adding, the properties cannot be null, while when updating they can (nulled properties are ignored).</p>
  <p><strong>Problem 1:</strong></p>
  <p>On my frontend, the user is asked to choose a list of tags from the database (multi select html). This is why <code>createPostRequest</code> has a <code>tags</code> property typed <code>TagDTO</code>. But, how can I use modelMapper to map, for example, the <code>createPostRequest</code> to the <code>Post</code> entity making sure that the tags exist in the database?</p>
  <p>if for example a user try to insert a tag that does not exist, I was thinking of doing something like this:</p>
  <pre class="lang-java prettyprint-override"><code>postEntity.setTags(tagService.findAllByIds(postEntity.getTagsId()));
  </code></pre>
  <p>This makes a lot of repetition in the code, because between create and update method of my entity in service, there is a lot of identical code.</p>
  <p><strong>Problem 2:</strong></p>
  <p>Based on my problem 1, how can I easily map my two DTOs to the same entity without repeating the code 2x?</p>
  <p><strong>Code example -</strong> <code>PostService</code> <strong>(see comment)</strong></p>
  <p>This is an example for the update, but there will be almost identical code for the <code>create</code>, so how do I proceed?</p>
  <pre class="lang-java prettyprint-override"><code>@Transactional
  public Post update(Integer postId, UpdatePostRequest request) {
      return Optional.ofNullable(this.getById(postId)).map(post -&gt; {
        // here how to map non-null properties of my request 
              // into my post taking in consideration my comment above?   
  
        postDAO.save(post);
  
        return post;
      }).orElseThrow(() -&gt; new ResponseStatusException(HttpStatus.NOT_FOUND));
  }
  </code></pre>
  <p>================================</p>
  <p><strong>UPDATE:</strong></p>
  <p>As requested, found the code bellow.</p>
  <p>The controller:</p>
  <pre><code>@RestController
  @RequestMapping(&quot;/v1/posts&quot;)
  public class PostController {
      RequestMapping(method = RequestMethod.POST, consumes = &quot;application/json&quot;, produces = &quot;application/json; charset=UTF-8&quot;)
      public ResponseEntity&lt;Object&gt; update(@Valid @RequestBody CreatePostRequest createPostRequest) {
          Post post = postService.create(createPostRequest);
          return new ApiResponseHandler(new PostDTO(post), HttpStatus.OK).response();
      }
  
      RequestMapping(value = &quot;/{postId}&quot;, method = RequestMethod.PUT, consumes = &quot;application/json&quot;, produces = &quot;application/json; charset=UTF-8&quot;)
      public ResponseEntity&lt;Object&gt; update(@Valid @RequestBody UpdatePostRequest updatePostRequest, @PathVariable Integer postId) {
          Post post = postService.update(postId, updatePostRequest);
          return new ApiResponseHandler(new PostDTO(post), HttpStatus.OK).response();
      }
  }
  </code></pre>
  <p>CreatePostRequest :</p>
  <pre><code>@Data
  public class CreatePostRequest {
      @NotNull
      @Size(min = 10, max = 30)
      private Sting title;
  
      @NotNull
      @Size(min = 50, max = 600)
      private String description
  
      @NotNull
      @ValidDateString
      private String expirationDate;
  
      @NotNull
      private List&lt;TagDTO&gt; tags;
  
      public List&lt;Integer&gt; getTagIds() {
          return this.getTags().stream().map(TagDTO::getId).collect(Collectors.toList());
      }
  }
  </code></pre>
  <p>UpdatePostRequest :</p>
  <pre><code>@Data
  public class UpdatePostRequest {
      @Size(min = 10, max = 30)
      private Sting title;
  
      @Size(min = 50, max = 600)
      private String description
  
      @ValidDateString
      private String expirationDate;
  
      private List&lt;TagDTO&gt; tags;
  
      public List&lt;Integer&gt; getTagIds() {
          return this.getTags().stream().map(TagDTO::getId).collect(Collectors.toList());
      }
  }
  </code></pre>
  <p>The service :</p>
  <pre><code>@Service
  @Transactional
  public class PostService {
      @Transactional
      public Post create(CreatePostRequest request) {
          ModelMapper modelMapper = new ModelMapper();
          Post post = modelMapper.map(request, Post.class);
  
          // map will not work for tags : how to check that tags exists in database ?
  
          return postDAO.save(post);
      }
  
      @Transactional
      public Post update(Integer postId, UpdatePostRequest request) {
          return Optional.ofNullable(this.getById(postId)).map(post -&gt; {
              ModelMapper modelMapper = new ModelMapper();
              modelMapper.getConfiguration().setSkipNullEnabled(true);
              modelMapper.map(request, post);
              
              // map will not work for tags : how to check that tags exists in database ?
              
              postDAO.save(post);
  
              return post;
          }).orElseThrow(() -&gt; new ResponseStatusException(HttpStatus.NOT_FOUND));
      }
  }
  </code></pre>