Open jaeuk520 opened 3 months ago
변환은 service 단에서 일어나는것이 더 일반적이라고 알고 있습니다. 사실 추상화를 기준으로 생각해보면 가장 하위 레이어인 repository에서 변환을 해 주는 것이 가장 깔끔하긴 하지만 repository에서 변환 작업이 발생할 경우 해당 쿼리메서드를 재사용하기 힘들다는 단점이 있어요. (DB에서 조회해온 결과값을 엔터티 갹체로 받지 않고 바로 DTO 객체로 받기 때문)
따라서 일반적으로는 서비스에서 변환해주는게 맞는거같아요:)
DTO를 서비스 단에서 반환해주는 더 중요한 이유가 있어서 공유하고자 합니다.
실제 운영 서버에서는 OSIV를 false로 해두고 사용하는 경우가 많은데 해당 경우 영속성 컨텍스트의 생존범위와 트랜잭션의 범위를 일치시켜주는 것이 좋기 때문에 서비스 클래스 위에 @Transactional 을 붙여 서비스부터 트랜잭션을 먹여 사용합니다.
따라서 OSIV가 false이며 entity가 반환되어야 하는 경우에는 service 단에서 처리하여 controller에서 지연로딩 할 일이 없도록 해야합니다.
다음과 같은 코드를 보자
위 코드는
service
단의 코드이며 request는DTO
이다.서비스 단에서
DTO
를Entity
로 변환시켜 DB에insert
하기 위해서 위와 같은 코드가 작성되었다.로직 자체는 문제가 없지만 다음과 같은 생각이 들었다.
DTO 내부에
정적 팩토리 메소드
,빌더 패턴
등을 사용하여toEntity()
,from()
와 같은DTO <-> Entity
변환 메소드를 만들어서 사용하는 일은 사실 이미 흔하다.결론부터 말하자면
DTO
가Entity
를 알고 의존하는 것은 크게 상관이 없다고 한다.하지만 역인
Entity
가DTO
에 의존하는 것은 매우 좋지 않다.DTO
에 있는 value1 field 이름이 변경되면Entity
에도 변경이 발생하기 때문에 자신의 책임의 여부와 관계 없는 코드로 인해 변경이 발생하는 것이다.따라서 위의 코드를 DTO 안에 정적 메소드를 사용하는 코드로 변경하면 아래와 같이 서비스 단의 코드가 더 깔끔해지게 된다.
위에서 제시한 방법은
DTO
를 "수동으로"Entity
로 변환하는 방법이다.Mapper를 사용하는 것에 대한 의견은
김영한
님의 답변을 인용했다.