웹 개발

[JPA] Entity to DTO, ModelMapper

노루아부지 2021. 7. 18. 23:12

 

API 통신에서 JPA를 사용할 때 entity를 그대로 return 하면 좋지 않습니다.

그 이유는 다음과 같습니다.

 

  1. entity 변화 시, API도 변경
    Database를 관리하다 보면 의외로 생각보다 Database가 변경되는 경우가 많습니다. API 통신에서 entity를 그대로 return 하는 경우에 Database가 변경되면 API도 변경되는 상황이 발생합니다.
    그러나 API는 특별한 경우가 아니면 변경되서는 안됩니다. API는 약속이며, 작게는 같은 팀의 직원과 크게는 다른 업체와 API 통신을 하는데, API가 변경되면 관련된 모든 사람이 코드를 수정해야 하는 상황이 발생합니다.
  2. 트래픽 증가
    요즘 인터넷이 빨라졌다고 하지만, 트래픽은 민감한 문제입니다. 특히, AWS 등의 클라우드 환경에서는 더 민감합니다. entity를 그대로 return 할 경우 불필요한 정보로 인해 트래픽이 증가할 수 있습니다.

 

API에서 사용하지 않고 단순 MVC 패턴에서 사용할때도 entity를 그대로 사용할 경우 문제가 발생합니다. 왜냐하면 View는 정말 많이 변경되는데 그때마다 entity를 수정할 수 없기 때문이죠

 

그렇다고 entity의 모든 컬럼을 일일이 DTO로 옮기려면 너무 작업이 많아지고 다음과 같이 실수로 인해 찾기 힘든 에러가 발생할 수 있습니다.

예를 들어 아래와 같은 entity와 DTO가 있다고 가정합니다.

@Entity
public class Book {
  private String title;
  private String author;
}

public class BookDTO {
  private String title;
  private String author;
}

 

여러 가지 휴먼 에러가 있지만 예시로 하나만 든다면, 아래와 같이 필드를 잘못 mapping 하는 경우가 있습니다.

private BookVO convert(BookDTO bookDTO) {
  BookVO bookVO = new BookVO();
  bookVO.setTitle(bookDTO.getTitle());
  // 다른 필드를 mapping했지만
  // 컴파일 에러가 없기 때문에
  // 운영 중 문제가 발생해도 디버깅이 어려울 수 있습니다.
  bookVO.setAuthor(bookDTO.getTitle());
  
  return bookVO;
}

 

 

하지만 ModelMapper를 사용해서 자동으로 mapping 할 경우 이런 휴먼 에러가 예방됩니다.

 

 

ModelMapper

 

ModelMapper의 목표는 오브젝트 매핑을 쉽게 만드는 것이다.
사람이 하는 것과 같이 규칙 기반으로 매핑방법을 자동으로 결정하는데,
이는 특정 케이스 핸들링을 위한 리팩토링 안전 API를 제공함으로써 가능하다
출처: modelmapper.org

 

 

Dependency

ModelMapper를 사용하기 위해서는 Dependency를 추가해야 합니다.

  • gradle
    compile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.0'​
  • maven
    <dependency>
      <groupId>org.modelmapper</groupId>
      <artifactId>modelmapper</artifactId>
      <version>2.3.0</version>
    </dependency>​

 

사용방법

ModelMapper를 사용하는 방법은 두 가지가 있습니다.

  1. 사용할 클래스에 ModelMapper 인스턴스 생성
    Book book = new Book();
    book.setTitle("노루");
    book.setSubTitle("아부지");
    
    ModelMapper modelMapper = new ModelMapper();
    BookDTO dto = modelMapper.map(book, BookDTO.class);​
  2. Bean으로 등록
    1. 먼저 modelMapper를 bean으로 등록합니다.
      import org.modelmapper.ModelMapper;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class RootContext {
        @Bean
        public ModelMapper modelMapper() {
          return new ModelMapper();
        }
      }
    2. @Autowired 등의 방법으로 bean을 주입하여 사용합니다.
      import org.junit.jupiter.api.Assertions;
      import org.junit.jupiter.api.Test;
      import org.modelmapper.ModelMapper;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      
      @SpringBootTest
      class BookDTOTest {
        @Autowired
        ModelMapper modelMapper;
      
        @Test
        public void testMapper2() {
          Book book = new Book();
          book.setTitle("노루");
          book.setSubTitle("아부지");
      
          BookDTO dto = modelMapper.map(book, BookDTO.class);
      
          Assertions.assertEquals(book.getTitle(), dto.getTitle());
          Assertions.assertEquals(book.getSubTitle(), dto.getSubTitle());
        }
      }​

 

 

 

참조

 

https://yoonho-devlog.tistory.com/69

 

dto와 entity를 구분해서 구현한 이유

본 카테고리의 포스팅은 스터디 프로젝트를 진행하며 생각한 내용을 정리한 것입니다. 스터디 프로젝트이며, 제가 나름대로 이해한 바를 적은 것이라 옳지 않은 정보가 있을 수 있습니다. 본

yoonho-devlog.tistory.com

https://jforj.tistory.com/93

 

[JPA] ModelMapper, Entity ↔ DTO 변환

안녕하세요. J4J입니다. 이번 포스팅은 엔티티와 DTO 간의 변환을 도와주는 ModelMapper에 대해 적어보는 시간을 가져보려고 합니다. JPA로 이것저것 해보다가 궁금한 사항이 생겼습니다. 데이터베이

jforj.tistory.com

https://baek.dev/post/15/

 

찾기 힘든 버그를 유발하는 Java DTO 컨버팅 노가다, 리팩토링하기 | 아웃풋 트레이닝

get/set 지옥에서 벗어나는 ModelMapper lib를 소개합니다. 자바에서 DTO 컨버팅을 할 때 멤버 필드를 하나하나 명시해서 변환을 많이 하곤 합니다. 이럴 경우 휴먼 에러가 발생 할 확률이 매우 높습니

baek.dev

728x90
loading