연관관계 - N:1, 1:N, 1:1, N:N
@ Entity
public class Comment {
...
@ ManyToOne
@ JoinColumn (name = "post_id" )
private Post post ;
}
@ Entity
public class Post {
...
}
@ Entity
public class Post {
...
// 추가
@ OneToMany (mappedBy = "post" )
private List <Comment > comments = new ArrayList <>();
}
One
쪽에 연관관계의 주인, 즉 외래키가 Many
가 아니라 One
쪽에 존재하여 이상한 구조
JoinColumn을 사용해주어야 하고 사용하지 않으면 중간 테이블 post_comment
이 하나 생기게 됨
@ Entity
public class Comment {
...
}
@ Entity
public class Post {
@ OneToMany
@ JoinColumn (name = "post_id" )
private List <Comment > comments = new ArrayList <>();
}
JPA 지원하는 Spec은 아니고 읽기전용으로 만들어 양방향처럼 사용할 수 있다.
@ Entity
public class Comment {
...
// 추가
@ ManyToOne (insertable = false , updatable = false )
private Post post ;
}
@OneToOne
은 지연 로딩으로 설정해도 결국 항상 즉시 로딩이 일어난다.
이유는 해당 외래키가 Null값인지 아닌지 판단하기 위해서 상대 테이블을 뒤져야 하기 때문이다.
@ Entity
public class Post {
...
}
@ Entity
public class Category {
...
@ OneToOne
@ JoinColumn (name = "post_id" )
private Post post ;
}
N:1 양방향 매핑과 유사하며 연관관계의 주인을 설정해준다.
@ Entity
public class Post {
@ OneToOne (mappedBy = "post" )
private Category category ;
}
RDB에서는 다대다를 테이블 두 개로 표현할 수 없기 때문에 중간에 테이블이 하나 생성이 된다.
@ManyToMany
를 사용해서 만들게 되면 중간 테이블에 추가 컬럼을 넣을 수 없고 매핑 키만 넣을 수 있는 문제가 발생한다.
그리고 쿼리를 예측하기 어렵다.
@ Entity
public class Student {
...
@ MannyToMany
@ JoinTable (name = "student_lecture" )
private List <Lecture > lectures = new ArrayList <>();
}
@ Entity
public class Lecture {
...
@ ManyToMany (mappedBy = "lectures" )
private List <Student > students = new ArrayList <>();
}
@ManyToMany
를 사용하지 않고 중간 테이블을 직접 만들어서 사용하면 위와 같은 문제를 해결할 수 있다.
@ Entity
public class StudentLecture {
@ Id @ GeneratedValue
private Long id ;
@ ManyToOne
@ JoinColumn (name = "student_id" )
private Student student ;
@ ManyToOne
@ JoinColumn (name = "lecture_id" )
private Lecture lecture ;
}
@ Entity
public class Student {
...
@ OneToMany (mappedBy = "student" )
private List <StudentLecture > studentLectures = new ArrayList <>();
}
@ Entity
public class Lecture {
...
@ OneToMany (mappedBy = "lecture" )
private List <StudentLecture > studentLectures = new ArrayList <>();
}