JPA

[Jpa] 단일 테이블 전략의 상속 관계 매핑 이슈

kkkkkkkkkkkk 2022. 8. 20. 14:48

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() 가 추가 될 것이다. 그러면 코드의 가독성이 떨어지고 유지보수가 어려워지고 테스트 하기에도 애매모호 하다.

 

 

리팩터링한 코드는 추상화한 인터페이스를 사용하여 각 아이템 마다 구현을 해주어야 하는 단점이 있지만 서비스 코드에는 간결한 코드를 가져갈 수 있다.