Back End/Spring Data JPA

[Spring JPA] 상속관계 매핑의 문제점 (@Inheritance)

DevPing9_ 2022. 1. 19. 00:55

상속관계 매핑에 대한 글은 이전에 한번 쓴적이 있다.

 

 

[Spring JPA] 슈퍼-서브타입 관계 모델링 (상속관계 매핑)

DB 모델링기법 중에 슈퍼-서브타입 모델링(엔티티가 상속관계를 이룸)이라는게 있는데, 논리모델은 같지만 실제 물리모델은 RollUp, RollDown, Identity 중 하나로 구현한다. [SQL] 슈퍼-서브타입 모델의

developer-ping9.tistory.com

 

 

"와 완전 좋잖아!!' 라고 극찬을 하며 개인적으로 진행중인 프로젝트에 적용하고자

코드를 다 뜯어고치면서 찾은 문제점을 공유하고자 한다.

 

 

# @Inheritance(strategy = InheritanceType.JOINED) 의 문제점

 1. Super타입클래스만 따로 조회할 수 없다. (Lazy Fetch가 안된다.)

1-1) Super타입클래스 레파지토리로도 조회가 안된다.
1-2) Sub타입클래스 레파지토리로도 조회가 안된다.
1-3) 반환타입을 DTO 로 잡으면 조회가 가능하다.

 

 이는 정말 치명적이라고 본다. 

 

 물리모델을 JOINED (Identity)로 구성하는데에는 여러가지 이유가 있겠지만, 

 JOINED 전략으로 나눠진 물리모델에 맞게끔 서비스 트랜잭션이 계속 발생했을때 얻는 이점이 하나도 없다.

 _ex) Super타입 엔티티에 isDeleted 와 같은 필드가 있다고 하자.
  Lazy Fetch가 된다면 삭제처리시 update를 super타입 엔티티에만 치면되는데 이러한 이점을 얻을 수 없다.  

 

 

[SQL] 슈퍼-서브타입 모델의 물리모델 결정기준 (feat. JPA)

DB 모델링기법 중에 슈퍼-서브타입 모델링(엔티티가 상속관계를 이룸)이라는게 있는데, 논리모델은 같지만 실제 물리모델은 RollUp, RollDown, Identity 중 하나로 구현한다. # 논리모델 * 전구모양의 x

developer-ping9.tistory.com

 

 

 

 

2. Sub타입클래스만 따로 조회할 수 없다. 

 

 위와 같은 맥락으로, Hibernate 가 항상 EAGER 전략을 사용하기 때문에 노답이다.

 

 ? 옵션조정하는게 있겠죠. 님이 못 찾으신거아니에요?

 

 내가 못 찾은거면 좋겠다. 구글링만 5시간째... stackOverFlow 에 있는 관련키워드 글을 30개 이상 읽은듯 하다.

 Hibernate 공식문서도 읽어보았다.

 (영어 그만...)

 

 10년전 글도 읽었다... ㅋㅋㅋㅋㅋㅋㅋㅋ

 

Polymorphic 'get' using hibernate, many to one, InheritanceType.JOINED

I have something like this.. A Car class that has one Seat from many seats. Seat has a sub class LeatherSeat. public class Car { private Seat seat; ... @ManyToOne(fetch = FetchType.LAZY)

stackoverflow.com

 

 아래 포스팅은 뭔가 전문가의 냄새가 풍긴다.

 

 읽어보면, EAGER Fetch를 최대한 지양하라고 적혀있고

 그에 따라 @Inheritance 를 쓰지말고 직접 OneToOne으로 구현하라고 적혀있다.

 

hibernate Tutorial - Performance tuning

Learn hibernate - Performance tuning

sodocumentation.net


 

# 마치며

 

 결국 @Inheritance 어노테이션으로 얻는 이점은 물리모델 매핑변환이 자유롭다는 점 하나이다.

 

 이를 위해, Lazy Loading을 포기하고 싶진 않다. 

 (Interface Projection 을 해도 조인이 되는건 막을 수 없다)

 

 그래서 필자는 앞으로 Lazy 지원기능이 붙지 않는 이상 @Inheritance는 쓸일이 없을 것 같다.

 

 레파지토리 메서드를 모두 오버라이딩하거나 QueryDSL로 모두 처리하고 싶다면 @Inheritance를 쓰셔도 된다.

 (추측컨데 레파지토리 메서드를 오버라이딩해도 아마 안될 것 같다,,,) 

 

그냥 물리모델을 직접 엔티티로 매핑하는게 위의 방법보다 훨씬 빠를 것이다.

 

 

 

 

 

 

 

 

 


 

 

 

Polymorphic 'get' using hibernate, many to one, InheritanceType.JOINED

I have something like this.. A Car class that has one Seat from many seats. Seat has a sub class LeatherSeat. public class Car { private Seat seat; ... @ManyToOne(fetch = FetchType.LAZY)

stackoverflow.com

 

 

728x90