JPA 도메인 매핑 관련하여 질문드립니다.

2017-05-22 16:06

신규 프로젝트를 진행하면서 JPA 도메인 연관관계 매핑을 다시하고 있는데 이 부분에서 궁금한 부분이 있어 질문 드립니다.

현재 테이블 구조가 하나의 중심 테이블을 기준으로 여러 서브 테이블이 붙어있는 구조입니다.

따라서 도메인 매핑을 할때 기본적으로 중심 테이블에 연관관계가 많아지는 이슈가 있습니다.

생각을 해보니 현재는 스펙이 작아 중심테이블에 연관관계가 많이 생길 것 같지는 않지만 계속해서 프로젝트가 커지다보면 중심 테이블에는 여러 연관관계가 생기는 이슈가 생길 것 같습니다.

질문드리고 싶은 요지는 이 중심 테이블을 조회하는 조건에 따라 여러개로 분리하고자 하고자 합니다.

예를 들면

기사 상세 페이지를 볼때의 중심테이블 도메인 별도 / 기사 리스트를 조회 할때의 중심 테이블 도메인 별도 이런식을 조회 상황에 맞게 도메인을 매핑 하고자 합니다. (물론 공통 필드는 상위 엔티티를 두어서 상속을 사용하고자합니다.)

이런 구조가 괜찮은 구조인지 질문드리고 싶습니다.

감사합니다.

3개의 의견 from SLiPP

2017-05-23 16:14

글 만으로 정확히 이해하기 힘들겠네요.

간략하게라도 테이블 구조와 객체 매핑 사이의 관계를 예시를 들어줄 수 있나요? 그림으로 보여줄 수 있으면 더 좋을 것 같고요. 지금 글 만으로는 상상이 잘 되지 않네요.

2017-05-24 09:59

제가 설명이 조금 부족했던것 같습니다. 추가로 설명 이어가면...

테이블 구조는 위와 같은 구조 입니다.

뉴스 기사라는 테이블이 송고 받고 있는 모든 기사를 가지고 있는 테이블인데 해당 테이블을 중심으로 많은 서브 테이블이 생깁니다.

예를들면 뉴스기사 테이블이 매체 아이디를가지고 있고 매체 테이블과 연관이 생기는 구조입니다.

기존 프로젝트에 뉴스기사 테이블에 모든 연관관계를 맺고있는데 (물론 Lazy 패치를 하고 있습니다.) 이로 인해서 뉴스기사를 조회해올때, 불필요한 패치가 일어나는 경우가 자주 발생합니다.

제가 새롭게 하고자 하는 도메인 매핑은 아래와 같습니다.

@MappedSuperclass
public abstract class News {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "news_type", insertable = false, updatable = false)
    @Enumerated(EnumType.STRING)
    private NewsType type;

    @Column(name = "news_report_date")
    private DateTime reportDate;

    @Column(name = "news_modify_date")
    private DateTime modifiedDate;

    // ... 뉴스기사가 가지는 기본 필드만 @MappedSuperClass를 이용해서 추상화한 객체를 만듭니다.


}

위와같이 연관관계가 없이 기본 필드만 가지는 추상 객체를 @MappedSuperClass로 만들어 주려고 합니다.


@Entity @Immutable @Table(name = "news") public class DetailNews extends News { @Column(name = "news_content") private String newsContent; @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "news_internal_relation", joinColumns = @JoinColumn(name = "news_id"), inverseJoinColumns = @JoinColumn(name = "internal_code_id") ) private Set<DetailInternalCode> internalCodeSet = Sets.newHashSet(); @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name ="news_master_id") private Set<DetailKeywordNewsList> keywordNewsLists = Sets.newHashSet(); }

그리고 실제로 사용하는 조회상황에 맞게 필요한 연관관계나 추가로 필요한 필드는 추상 객체를 상속받아서 구현 하고자 합니다. (도메인 매핑 코드는 위와 같습니다.)

정리하면 @MapeedSuperClass로 정의한 추상 객체에서는 연관관계를 가지지 않고 해당 테이블에서 최소한으로 필요하다고 생각하는 필드만 정의해두고 실제 쿼리 상황에 맞게 해당 추상객체를 상속받아서 연관관계를 쿼리상황에 맞게 구상하고자 합니다.

이러한 구조로 진행하면 후에 추가 구현 사항이 있을때 마다 도메인 매핑을 쿼리 상황에 맞게 다시해주는 이슈가 있을것이라 생각되지만, 유지보수 측면에서는 해당 쿼리상황에 맞는 도메인만 수정해주면 되니 조금 더 유연하지 않을까 생각을 했습니다.

제 설명이 잘 되었는지 모르겠지만 혹시 이러한 구조에 대해서 조언을 부탁드릴 수 있을까요?

2017-05-24 12:52

전체적인 구조 이해했습니다.

현재 요구사항 측면에서는 괜찮은 접근 전략이라고 생각합니다. 각 상황에 따라 매핑을 달리한다면 복잡도를 줄일 수 있는 측면에서 의미가 있을 것 같네요.

각 도메인 모델에서 발생하는 중복 로직들이 있을텐데 그런 중복들만 잘 관리하면 될 것 같네요.

향후 복잡도에 따라 지금보다 더 세분화된 모델들 만들고 hierarchy 구조가 되는 방향으로 리팩토링해 나간다면 유지보수 측면에서도 좋은 접근 방식이라 생각되네요.

저도 위와 같은 구조로 적용한 경험은 없는 상태에서 남기는 답변이라 도움이 될지 모르겠네요. 다음에 만나면 결과가 어떠했는지 듣고 싶네요.

의견 추가하기

연관태그

← 목록으로