[Jpa] 단일 테이블 전략의 상속 관계 매핑 이슈
Item 테이블을 단일 테이블 전략으로 만들어 발생한 이슈에 대해 포스팅 해보겠습니다.
Book, Movie, Album 이라는 엔티티의 공통 속성을 뽑아 Item 이라는 엔티티를 상위 타입으로 만들었다.
여기서 save() 를 하는 코드에서 문제가 발생한다.
Item이 상위 타입이므로 하위 타입이 들어와도 저장이 되지만 web 계층에서 dto를 보내어 저장할 때가 애매모호 하다.
처음 구현 한 코드는 아래와 같다.
각각의 아이템 마다 조건문으로 타입 체크를 하고 dto에서 엔티티로 변환하여 save() 하는 코드이다.
해당 아이템의 타입 체크를 하여 타입에는 문제가 되지 않는다.
하지만 아이템 종류들이 추가 될 때 마다 saveItem() 안에 조건문과 save() 메소드가 추가 되어야 한다.
아이템의 종류가 100개 이상 일 때는?? 생각만 해도 코드가 복잡해진다.
이러한 코드를 개선해보자 한다.
아래의 블로그에 유익한 내용들이 많으니 참조 바랍니다.
참조
https://k3068.tistory.com/80?category=873366
어느 패턴을 사용해야 정답일까요??
게시판 통합 댓글 기능을 만들면서 생각했던 고민과 코드 구조에대해 말하고자 한다. 해당 기능의 목표는 Board 와 댓글간 연관 관계는 없다. 단 Reply Table 에서 각각의 Board 의 ID 와 Type 정보를 들
k3068.tistory.com
먼저 아래와 같은 인터페이스를 생성한다.
public interface ItemConverter {
boolean isTypeCheck(ItemType itemType);
<T extends Item> T convertItem(ServiceItemDto serviceItemDto);
}
isTypeCheck() 타입 체킹을 하는 메소드
covertItem() dto를 받아 엔티티로 변환해주는 컨버터 메소드
각각의 아이템 별로 위의 인터페이스를 구현하여 추상화 작업을 진행한다.
@Component
public class AlbumItemConverter implements ItemConverter {
@Override
public boolean isTypeCheck(ItemType itemType) {
return ItemType.ALBUM.equals(itemType);
}
@Override
public Item convertItem(ServiceItemDto serviceItemDto) {
return serviceItemDto.toAlbumEntity();
}
}
Book 과 Movie 도 마찬가지로 구현해준다.
서비스 클래스에 List<ItemConverter> 를 추가한다.
맨 처음 saveItem() 메소드 보다 더욱 간결해졌고 추상적인 코드로 바뀌었다.
처음 코드의 문제점은 아이템 종류가 추가 될 때 조건문과 save() 가 추가 될 것이다. 그러면 코드의 가독성이 떨어지고 유지보수가 어려워지고 테스트 하기에도 애매모호 하다.
리팩터링한 코드는 추상화한 인터페이스를 사용하여 각 아이템 마다 구현을 해주어야 하는 단점이 있지만 서비스 코드에는 간결한 코드를 가져갈 수 있다.