본문 바로가기
JAVA/SpringBoot

JPA의 관계 매핑: @OneToMany 와 @ManyToOne

by GangDev 2024. 3. 25.

 

@OneToMany 와 @ManyToOne 어노테이션은 JPA 에서 엔티티 간의 관계를 매핑할 때 사용된다.

 

@ManyToOne >>
"다대일" 관계로, 많은(many) 측에서 사용된다.
데이터베이스에서 이 관계는 foreign key를 사용하여 구현된다.
@JoinColumn 어노테이션과 함께 사용되어서 foreign key의 매핑을 지정한다.
(ex: 여러 User 엔티티가 하나의 Department 엔티티에 속할 때, User 엔티티 내에 @ManyToOne 관계가 정의된다)

 

@OneToMany >>
"일대다" 관계로, 하나(one) 측에서 사용된다.
보통, 컬렉션이나 리스트 같은 컨테이너 타입과 함께 사용된다.
주로 조인 테이블을 사용해서 구현되며, @JoinColumn을 사용하여 매핑을 정의할 수도 있다.
(ex: 하나의 Department' 가 여러 User 를 가질 때, Department 엔티티 내에 @OneToMany 관계가 정의된다)

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // ...

    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;

}

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // ...

    @OneToMany(mappedBy = "department")
    private List<User> users = new ArrayList<>();

}

 

위 예시에서, 각 User는 하나의 Department 에 속하며(@ManyToOne), 하나의 Department 는 여러 user를 가질 수 있다(@OneToMany). @OneToMany 에서 mappedBy 속성은 역방향 매핑 목적으로 사용된다.(User 클래스의 department 필드를 참조한다)
User 는 ManyToOne 을 사용하여 Department를 참조하고, 이 관계에서 User 가 소유자다.
Department 에서 User 로의 관계는 관리되지 않으며, 오직 User 에서 Department 로의 관계만이 관리된다.

 

(mappedBy 는 JPA에서 양방향 관계를 설정할 때 사용된다. 관계의 소유자 측이 아닌 역방향 측에서 사용된다. 연관 관계에서 소유자 측의 필드 이름을 가리키며, 이를 통해 JPA는 두 엔티티 간의 관계가 어떻게 매핑되어 있는지 파악한다.
(사용하는 이유: 연관 관계의 주도권을 명확히 함. mappedBy를 사용함으로써 JPA가 관계의 소유자 측의 변경사항만을 데이터베이스에 반영함. mappedBy 가 없으면 JPA는 양쪽 엔티티 모두에서 관계 데이터를 유지하려고 하므로 성능 문제를 일으킬 수 있음, mappedBy 는 이러한 불필요한 업데이트 쿼리를 방지함)

 

---

24년 1월 11일 작성된 글입니다