연관관계의 주인
JPA에서 두 엔티티가 연관관계를 맺을 때, 실제 외래 키(FK)를 관리하는 쪽을 가리키는 개념입니다.
핵심 특징
- FK를 가진 테이블 쪽이 연관관계의 주인이 됩니다.
- 주인이 아닌 쪽은
mappedBy속성에 주인 엔티티의 필드명을 지정합니다. - 연관관계의 주인만 FK 값을 등록·수정할 수 있고, 주인이 아닌 쪽은 조회만 가능합니다.
코드 예시
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(mappedBy = "user", fetch = FetchType.LAZY) // 주인이 아님
private Account account;
}
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY) // FK(user_id)를 가진 쪽 = 주인
private User user;
}
왜 주인을 정해야 하는가
객체의 양방향 연관관계는 사실 두 개의 단방향 참조에 불과하지만, 테이블은 FK 하나로만 관계를 표현합니다. 어느 한쪽이 FK 변경을 책임지지 않으면 두 참조가 서로 다른 상태로 갱신될 수 있기 때문에, JPA는 주인 쪽의 변경만 DB에 반영합니다.
@OneToOne 양방향에서 주의할 점
주인이 아닌 쪽(mappedBy를 사용하는 쪽)을 조회하면 지연 로딩(Lazy Loading)이 동작하지 않고 즉시 추가 쿼리가 실행됩니다.
- 주인이 아닌 엔티티는 FK가 없어 연관 엔티티의 존재 여부를 알 수 없습니다.
- JPA는 프록시로 초기화할지
null로 초기화할지 결정할 수 없어, 연관 엔티티 존재 여부를 확인하는 쿼리를 즉시 실행합니다. @OneToMany,@ManyToOne은 컬렉션이라 빈 컬렉션 프록시로 초기화가 가능하지만,@OneToOne은 단일 참조이기 때문에 이 문제가 발생합니다.
JPA 구현상의 한계이므로, 단방향으로 모델링하거나 Lazy Loading이 정말 필요한지 다시 검토해야 합니다.
핵심 정리
연관관계의 주인은 FK를 가진 쪽이며, 주인이 아닌 쪽은 조회만 가능합니다. 특히 @OneToOne 양방향 관계에서 주인이 아닌 쪽을 조회하면 Lazy Loading 설정과 무관하게 즉시 추가 쿼리가 발생하므로 주의해야 합니다.