Spring - JPA의 mapped by

jpa 이해하기

Posted by Yan on July 6, 2024

JPA에서 Mapped by

1. Mapped by란 무엇인가?

JPA에서 @OneToMany@ManyToMany 관계를 정의할 때 사용하는 어노테이션이다. 주체 엔티티에서 역관계 엔티티를 참조하는 필드에 사용하며, 역관계 엔티티에서 주체 엔티티를 참조하는 필드를 찾도록 지시하는 역할을 한다. 주체(owning) 엔티티에서 역방향 관계(inverse relationship)를 정의할 때 사용된다. 쉽게 말하면, 1쪽에서 N쪽을 관리하지 않는 관계를 나타낸다.

  • 특히, 1:N 관계에서 자주 사용되며, 객체와 테이블 간의 매핑을 명확하게 하여 코드를 이해하기 쉽게 만들어 준다.

예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Entity
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(mappedBy = "parent")
    private List<Child> children = new ArrayList<>();

    // ...
}

@Entity
public class Child {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;

    // ...
}

위 예시에서 Parent 엔티티는 Child 엔티티의 주체 엔티티이며, Child 엔티티는 Parent 엔티티의 역관계 엔티티다.

Parent 엔티티의 children 필드에는 @MappedBy(“parent”) 어노테이션이 지정되어 있다. 이는 Child 엔티티의 parent 필드가 Parent 엔티티를 참조한다는 것을 의미한다. 즉, JPAChild 엔티티를 조회할 때 parent 필드를 통해 자동으로 Parent 엔티티를 찾아 연결한다.

활용예시

  • 1:N 관계: 한 엔티티가 여러 다른 엔티티를 가질 수 있는 경우 (예: 사용자와 주문, 상품과 카테고리)
  • 양방향 관계: 두 엔티티가 서로 참조하는 경우 (예: 게시글과 댓글)
  • 순환 참조 방지: 순환 참조가 발생할 가능성이 있는 관계를 정의할 때 (예: 부서와 직원)

2. Mapped by의 장점

  • 관계 설정이 명확해짐: 어떤 엔티티가 관계를 소유하는지 명확하게 드러낸다.
  • 코드 간결성 향상: 관계 설정 코드가 간결하고 읽기 쉬워진다.
  • 유지 관리 용이: 관계 변경 시 한 곳만 수정하면 된다.

3. Mapped by의 문제점

  • 양방향 관계에서 주의: @MappedBy단방향 관계에서만 사용해야 한다. 양방향 관계에서 @MappedBy@JoinColumn을 함께 사용하면 오류가 발생할 수 있다.
  • cascade 속성 설정: @MappedBy를 사용하면 cascade 속성을 직접 설정할 수 없다. @OneToMany 또는 @ManyToMany 어노테이션에서 cascade 속성을 설정해야 한다.
  • orphan removal: @MappedBy를 사용하면 orphan removal 기능을 직접 설정할 수 없다. @OneToMany 또는 @ManyToMany 어노테이션에서 orphanRemoval 속성을 설정해야 한다.

4. Mapped by 사용 시 주의점

  • 주체 엔티티와 역관계 엔티티를 명확하게 구분: @MappedBy주체 엔티티에서만 사용해야 한다.
  • 양방향 관계에서는 사용 금지: @MappedBy단방향 관계에서만 사용해야 한다.
  • cascade 및 orphanRemoval 속성 설정: @MappedBy를 사용하면 cascadeorphanRemoval 속성을 @OneToMany 또는 @ManyToMany 어노테이션에서 설정해야 한다.

5. Mapped by 대신 @JoinColumn 사용

  • 양방향 관계: @MappedBy는 단방향 관계에서만 사용해야 하기 때문에, 양방향 관계에서는 @JoinColumn을 사용하는 것이 좋다.
  • cascade 및 orphanRemoval 속성 제어: @JoinColumn을 사용하면 cascadeorphanRemoval 속성을 자유롭게 설정할 수 있다.

Mapped by vs. JoinColumn

구분 Mapped by JoinColumn
사용 위치 주체 엔티티 역방향 엔티티
관계 설정 역방향 관계 주체 방향 관계
관리 엔티티 주체 엔티티가 역방향 엔티티를 직접 관리하지 않음 주체 엔티티가 역방향 엔티티를 직접 관리
순환 참조 가능성 높음  

6. 결론

Mapped by는 JPA에서 @OneToMany@ManyToMany 관계를 정의할 때 유용한 어노테이션이지만, 양방향 관계cascade, orphanRemoval 속성 제어가 필요한 경우에는 @JoinColumn 사용을 고려해야 한다.

reference

learn-jpa-hibernate