@ManyToOne : 다대일
@OneToMany : 일대다
@OneToOne : 일대일
@ManyToMany : 다대다
@OneToOne은 Entity에 대상 Entity가 있으면 대상 Entity가 있는지 없는지 확인해야하므로
지연 방식으로 해도 Select 쿼리가 나가게 되기 때문에 지연 방식 설정에 상관없이 즉시 로딩 고정이다.
@ManyToMany는 쓰지 않는다. 객체 중심 설계는 다대다가 가능하지만,
이를 DB에 매핑하면 다대일 일대다의 중간 테이블이 생성되는데
자동으로 생성되는 이 중간 테이블을 관리하는게 불편하기 때문에 가급적 피한다.
Member와 Team이 N:1 관계를 가지며 Member의 FK는 Team_Id라고 가정할 때
테이블 참조에서는 Team_Id만으로 양쪽 테이블의 연관 관계를 알 수 있다(양방향).
객체 참조에서는 Member는 필드에 참조하기 위한 Team Entity가 필요하고(단방향)
TEAM은 필드에 참조하기 위한 Member List가 필요하다(단방향).
JPA에서는 Member의 Team Entity에 @JoinColumn(name = "Team_Id")를 달아서 FK를 설정하고
Team의 Member List에 @OneToMany(mappedBy = "Member Entity의 Team 필드명")를 달아준다.
(MEMBER LIST는 관례적으로 NULL_POINTER_EXCEPTION을 피하기 위해 ARRAY LIST로 초기화해둔다)
위에서 Member의 Team을 바꾸고 싶을 때 Member의 Team 필드의 값을 바꿀 수도 있고
Team의 Member List를 수정할지 딜레마가 생긴다.
따라서 둘 중 하나로 주인을 정해 외래 키를 관리해야한다.
-> 주인은 DB 등록과 수정이 가능하고 mappedBy는 읽기만 가능하다.
JPA에서는 mappedBy의 대상이 주인이다.(위 예제에서는 Member.Team이 주인)
DB 쿼리와 헷갈리지 않기 위해서 일반적으로 실질적으로 FK를 가지는 쪽을 주인으로 설정한다(ManyToOne)
객체지향적으로 설계하기 위해서 연관관계 편의 메소드도 넣어두면 좋다.
JPA 양방향 매핑시에 서로의 객체를 계속 호출하는 무한 루프를 조심해야한다.
ex) lombok으로 toString을 만들어 필드의 객체가 서로를 계속 호출하는 경우
Controller에서 Entity를 그대로 반환하는 경우
최대한 단방향 매핑으로 설계를 끝내는 것을 권장
-> 테이블에 영향을 주지 않기 때문에 양방향은 필요할 때 추가하면 된다.