연관관계의 매핑 방향성, 그리고 주인에 대한 정리가 마무리 되면, 이 매핑을 어떻게 하고 상황에 따라 주인을 어떻게 설정해야 하는지를 알아야 한다.
연관관계의 객체 관계를 보고 이를 판단하게 된다.
연관관계는 흔히 일대일, 일대다, 다대일, 다대다 로 구분된다.
이중에 이번 포스팅은 다대일, 일대다를 이야기해볼 것이다.
데이터베이스를 배울 때에는 일대다에 대해서 배운 적이 없었다. 그저 다대일이라고 이야기했을 뿐이다.
JPA에 대해서 알기 전에, 데이터베이스의 다대일은 어떻게 이루어지는지 생각해보아야 한다.
다 쪽에서 외래키를 가지고, 일 쪽의 기본키를 가지게 된다. 이 외래키는 유니크하지 않다.
그래야, 여러 객체가 한 객체의 기본키를 외래키로 가질 수 있다.
다대일의 예시를 보면서 이야기하면 알기 편할 것 같다.
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ORDERS_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MEMBER_ID")
@OnDelete(action = OnDeleteAction.CASCADE)
private Member member;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "CITY")
private String city;
@Column(name = "STREET")
private String street;
@OneToMany(mappedBy = "member")
private List<Order> myOrder = new ArrayList<>();
두 개의 객체를 보면서 이야기를 이어보자면, 아까 명시했듯이 다 쪽이 외래키를 가지는, 연관관계의 주인이다.
그렇기에 @JoinColumn(name "MEMBER_ID")로 외래키의 이름을 어떻게 저장하고, 어떻게 처리될지를 정했다.
다(Order) : 1(Member)이기에 @ManyToOne으로 되어있다. FetchType은 후에 기술하도록 하겠다.
이렇게만 해도 단방향 연관관계가 성립한다.
양방향 연관관계를 위해 반대쪽 Member에 myOrder이라는 list가 @OneToMany(mappedBy = "member")라는 어노테이션을 가지고 있다.
이는 외래키로 인해 Order에서 member라는 변수명으로 매핑되어진 객체라는 뜻이며, 이를 통해 데이터베이스에서 읽기전용으로 Order를 List로 불러올 수 있게 해준다.
반대의 일대다에 대해서 정리를 하기 앞서, 잘 쓰이지 않는 다는 것을 알아야 한다.
과연, 데이터베이스에서 여러 기본키들을 외래키 하나에 저장한다는게 가능키가 하겠나...!!!
절대 안된다.
일단 이게 얼마나 복잡하냐면, 일쪽이 연관관계의 주인이지만 다 쪽이 외래키를 가진다. 일쪽은 외래키를 가질 수 없으므로...
하지만 JPA에서는 연관관계의 주인을 일 쪽으로 판단한다.
즉, 자바에서 처리할 때에는 일 쪽이 주인인 것 같지만, 데이터베이스에 쿼리문을 날릴 땐 다 쪽이 주인인 것 처럼 쿼리를 날린다.
주인 쪽에 @JoinColumn을 제대로 써주지 않는다면 두 테이블을 조인해서 하나의 테이블로 데이터를 가져오는 괴상한(?) 참사를 볼 수 있다.
결론 : 다대일을 애용하자....
'스프링 공부 > JPA' 카테고리의 다른 글
[JPA] 13. 다대다 매핑(이걸 매핑이라 부를까....?) (0) | 2022.11.03 |
---|---|
[JPA] 12. 일대일 매핑(부제 : 짝짜쿵) (0) | 2022.11.03 |
[JPA] 10. 연관관계 매핑의 방향성, 그리고 주인 (0) | 2022.11.02 |
[JPA] 9. 객체지향에서 연관관계를 만들어야 하는 이유 (0) | 2022.11.02 |
[JPA] 8. 데이터베이스 스키마 자동생성 (0) | 2022.10.20 |