Computer Science/Database

[JPA] Entity Mapping

Kim Jinung 2023. 5. 23. 19:54

JPA Cache

1st Cache: 트랜잭션 단위

2nd Cache: 앱 내에서 공유하는 캐시


Why need default constructor?

JPA는 동적으로 객체를 생성하기 위해서 자바 리플렉션 기능 등을 사용한다. 이를 위해서 기본으로 제공해주어야 한다.


Undirectional Mapping vs Bidirectional Mapping

양방향 매핑은 2개의 단방향 매핑이다. 

디비 테이블은 외래키 조인을 통해 양방향 관계가 성립된다. 반면 객체는 단뱡향 2개로 양방향 참조를 구현해주어야 한다. 

일반적으로 FK를 가지고 있는 객체가 연관 관계의 주인이 되고, 반대편 객체는 읽기 전용으로만 사용한다. mappedBy 파라미터의 역할이 여기에 해당한다. 즉 JPA는 mappedBy로 지정된 필드는 읽기 전용으로만 취급하므로 해당 엔티티 객체의 값을 변경하더라도 디비에 반영하지 않는다. (여기서 매핑 오너가 FK키를 가진 쪽이 되는 이유는, 해당 엔티티가 Many 관계에 해당하고 One 관계에 해당하는 쪽이 PK키를 가지는 입장을 생각해보면 된다. FK키를 가진쪽에서 반대 방향 객체를 주로 참조하고, 역으로 PK를 가진 쪽에서는 FK키를 가진 테이블을 참조할 일이 없다. FK키를 가진쪽에서 조인걸기 때문에. 반면에 객체 입장에서는 이 관계로도 참조할 때가 있는데 이를 OneToMany 형태로 매핑해주고 컨테이너 형태(List)로 FK키를 가진 엔티티를 담아주는 게 그 예시다. 이부분이 굉장히 헷갈렸다.)

 

Many에 해당하는 엔티티에서 값을 추가할 때 반대 반향에 있는 읽기 전용 필드를 가진 객체에도 값을 추가해주는 것이 좋다. 값 추가후 곧바로 엔티티 매니저를 통해 flush를 호출하여 디비에 반영하는 경우에는 문제가 발생하지 않지만, flush 이전에 반대쪽 엔티티에서 값을 조회하고자 하는 경우 아직 디비에 반영이 되지 않은 상태이므로 추가한 값을 읽을 수 없다. 캐쉬에 있는데 왜 못읽을까? 예를 들어서 엔티티 A와 B가 양방향 관계이고 A가 Many에 해당하는 관계일 때 A의 FK를 참조하는 엔티티에 값을 변경할 때 A와 B는 그 자체로 매핑된 관계가 아니라, 각자 디비에서 값을 가져온다.

 

  1. A에서 FK를 참조하는 값 변경
  2. 영속성 컨텍스트에 반영 됨: 아직 디비에 반영이 안 된 상태
  3. B가 값 조회
  4. 영속성 컨텍스트에서 조회. 이때 조회하는 값은 A 엔티티에 의해 영속성 컨텍스트에 캐싱된 값이 아니라, 엔티티 매니저가 B 객체를 디비에서 조회하는 별개의 데이터

즉 A는 FK를 가지고 조인쳐서 객체를 가지고 온다. 이때 FK를 가지고 조인한 값을 변경하는 것이다. 이때 변경한 값을 디비에 반영하지 않으면 B는PK(A의 FK) 값을 가지고 값을 조회하더라도 아직 값이 반영되지 않았으니까 변경 사항을 감지할 수 가 없다. 이 과정에서 문제가 발생하니까 양방향 관계에서 Many 측에서 값을 변경할때 반대 방향에 있는 mappendBy를 사용하는 엔티티에도 값을 추가로 넣어주는 것이 원자성을 고려할 때 더 깔끔하다. 그리고 mappedBy로 매핑된 필드는 읽기 전용이라 어차피 디비에도 반영이 안된다. 다만 애플리케이션 로직 상에서는 위 문제를 고려해야한다.


Mapping Design

단방향 매핑만으로 설계가 완성되어야 한다. 양방향 매핑은 JPQL등의 쿼리에서 조회가 빈번한 경우 추가로 걸어주는 것이 좋다. 

 

1:N, N:N 등의 관계는 지양한다. N:1, 1:1 관계가 기본이다. N:N은 데이터 볼륨이 커질수록 카디널리티 사이즈가 커져서 디비 성능에 악영향을 준다. 1:N은 N:1과 반대로 N이 아닌 1쪽에서 외래키를 관리한다. 디비 관점에서 FK를 가진 쪽이 Many이므로 정상적인 매핑은 아니다.


조금 더 깔끔한 정리가 필요하다.. 

핵심은 단방향 매핑, N:1, 1:1 그리고 왜 FK 가진 쪽이 매핑 오너가 되는지, 왜 PK를 가진 쪽은 매핑 시 컨테이너 형태로 걸어주는지를 이해하면 된다.