엔티티
// Non Owner Entity
@Entity
public class Post {
@Id
@Column(name = "post_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Post [id=" + id + ", title=" + title + ", content=" + content + "]";
}
public Post() {
}
public Post(String title, String content) {
this.title = title;
this.content = content;
}
}
// Owner Entity
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String content;
// #1 ~ #7
// #A, #B
// @ManyToOne
// private Post post;
// #8
// @ManyToOne(cascade = CascadeType.PERSIST)
// private Post post;
// #C
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "post_id")
private Post post;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
@Override
public String toString() {
return "Comment [id=" + id + ", content=" + content + "]";
}
public Comment() {
}
public Comment(String content, Post post) {
this.content = content;
this.post = post;
}
}
테스트 코드
public class Test2 {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
Post post = new Post("title", "content");
Post post2 = new Post("title2", "content2");
Post post3 = new Post("title3", "content3");
em.persist(post);
em.persist(post2);
em.persist(post3);
Comment comment = new Comment("content", post);
Comment comment2 = new Comment("content2", post);
Comment comment3 = new Comment("content3", post2);
em.persist(comment);
em.persist(comment2);
em.persist(comment3);
em.flush();
em.clear();
tx.commit();
}finally {
em.close();
}
}
}
@ManyToOne 단방향 조회
CASE1
Post 조회
{
Post findPost = em.find(Post.class, 1);
System.out.println(findPost);
}
쿼리실행
Hibernate:
select
p1_0.post_id,
p1_0.content,
p1_0.title
from
Post p1_0
where
p1_0.post_id=?
Post [id=1, title=title, content=content]
CASE2
Comment 조회
Comment 엔티티의 post에 대한 @ManyToOne 의 FetchType 이 EAGER
{
Comment c1 = em.find(Comment.class, 1);
System.out.println(c1);
// Comment 와 연관된 Post 를 가져올 때 다시 sql 수행 (X)
System.out.println(c1.getPost());
}
쿼리실행
Hibernate:
select
c1_0.id,
c1_0.content,
p1_0.post_id,
p1_0.content,
p1_0.title
from
Comment c1_0
left join
Post p1_0
on p1_0.post_id=c1_0.post_id
where
c1_0.id=?
Comment [id=1, content=content]
Post [id=1, title=title, content=content]
CASE3
Comment 조회
Comment 엔티티의 post에 대한 @ManyToOne 의 FetchType 이 LAZY
{
Comment c1 = em.find(Comment.class, 1);
System.out.println(c1);
// Comment 와 연관된 Post 를 가져올 때 다시 sql 수행
System.out.println(c1.getPost());
}
첫번째 쿼리는 em.find(Comment.class, 1)에 의해 comment를 조회하는 select문이다.
현재 LAZY여서 comment엔티티의 person에는 프록시 객체가 저장된다.
System.out.println(c1.getPost())로 인해 실제 person 값을 사용시 person에 대해 프록시 초기화가 발생해 person을 조회하는 select문이 발생한다.
쿼리실행
Hibernate:
select
c1_0.id,
c1_0.content,
c1_0.post_id
from
Comment c1_0
where
c1_0.id=?
Comment [id=1, content=content]
Hibernate:
select
p1_0.post_id,
p1_0.content,
p1_0.title
from
Post p1_0
where
p1_0.post_id=?
Post [id=1, title=title, content=content]
@ManyToOne, @OneToMany 양방향 조회
엔티티
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
private String content;
// #1 ~ #9
// #A, #B, #D
@OneToMany(mappedBy="post") // bi-directional relationship 규정 ( Comment Entity 의 자신 Post 필드 명 )
private List<Comment> comments;
// #10
// @OneToMany(cascade = CascadeType.PERSIST)
// private List<Comment> comments;
// #C
// @OneToMany(mappedBy="post", fetch = FetchType.EAGER) // bi-directional relationship 규정 ( Comment Entity 의 자신 Post 필드 명 )
// private List<Comment> comments;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
@Override
public String toString() {
return "Post [id=" + id + ", title=" + title + ", content=" + content + "]";
}
public Post() {
}
public Post(String title, String content) {
this.title = title;
this.content = content;
}
}
// Owner Entity
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String content;
// #1 ~ #8, #10
// #A, #B, #C
// @ManyToOne
// @JoinColumn(name="post_id") // 생성되는 Comment table 에 post_id 컬럼이 생성 (FK)
// private Post post;
// #9
// @ManyToOne(cascade = CascadeType.PERSIST)
// @JoinColumn(name="post_id") // 생성되는 Comment table 에 post_id 컬럼이 생성 (FK)
// private Post post;
// #D
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="post_id") // 생성되는 Comment table 에 post_id 컬럼이 생성 (FK)
private Post post;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
@Override
public String toString() {
return "Comment [id=" + id + ", content=" + content + "]";
}
public Comment() {
}
public Comment(String content, Post post) {
this.content = content;
this.post = post;
}
}
테스트 코드
public class Test2 {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
Post post = new Post("title", "content");
Post post2 = new Post("title2", "content2");
Post post3 = new Post("title3", "content3");
em.persist(post);
em.persist(post2);
em.persist(post3);
Comment comment = new Comment("content", post);
Comment comment2 = new Comment("content2", post);
Comment comment3 = new Comment("content3", post2);
em.persist(comment);
em.persist(comment2);
em.persist(comment3);
em.flush();
em.clear();
tx.commit();
}
}
CASE1
Post 조회
@OneToMany 의 FetchType 이 LAZY
{
Post findPost = em.find(Post.class, 1);
System.out.println(findPost);
// Comment 가 필요할 때 다시 sql 수행
System.out.println(findPost.getComments());
}
첫번째 쿼리는 em.find(Post.class, 1)에 의해 발생한다.
Post엔티티가 comments에 대해 LAZY라 comment를 같이 조회하지 않는다.
comment의 실제 데이터 사용시 comment에 대해 조회하는 select문이 발생한다.
Comment 엔티티 쪽에서 post에 대해 FetchType 이 LAZY이든 EAZER이든 comment에 대해 조회하는 select문 결과는 똑같다.
실행쿼리
Hibernate:
select
p1_0.id,
p1_0.content,
p1_0.title
from
Post p1_0
where
p1_0.id=?
Post [id=1, title=title, content=content]
Hibernate:
select
c1_0.post_id,
c1_0.id,
c1_0.content
from
Comment c1_0
where
c1_0.post_id=?
CASE2
Comment 조회
@ManyToOne 의 FetchType EAGER
{
Comment c1 = em.find(Comment.class, 1);
System.out.println(c1);
// Post 사용할 때 다시 sql 수행 (X)
System.out.println(c1.getPost());
}
실행결과
Hibernate:
select
c1_0.id,
c1_0.content,
p1_0.id,
p1_0.content,
p1_0.title
from
Comment c1_0
left join
Post p1_0
on p1_0.id=c1_0.post_id
where
c1_0.id=?
Comment [id=1, content=content]
Post [id=1, title=title, content=content]
CASE3
Post 조회
@OneToMany 의 FetchType EAGER
{
Post findPost = em.find(Post.class, 1);
System.out.println(findPost);
// Comment 가 필요할 때 다시 sql 수행 (X)
System.out.println(findPost.getComments());
}
실행쿼리
Hibernate:
select
p1_0.id,
p1_0.content,
p1_0.title,
c1_0.post_id,
c1_0.id,
c1_0.content
from
Post p1_0
left join
Comment c1_0
on p1_0.id=c1_0.post_id
where
p1_0.id=?
Post [id=1, title=title, content=content]
CASE4
Comment 조회
@ManyToOne 의 FetchType LAZY
{
Comment c1 = em.find(Comment.class, 1);
System.out.println(c1);
// Post 사용할 때 다시 sql 수행
System.out.println(c1.getPost());
}
쿼리실행
Hibernate:
select
c1_0.id,
c1_0.content,
c1_0.post_id
from
Comment c1_0
where
c1_0.id=?
Comment [id=1, content=content]
Hibernate:
select
p1_0.id,
p1_0.content,
p1_0.title,
c1_0.post_id,
c1_0.id,
c1_0.content
from
Post p1_0
left join
Comment c1_0
on p1_0.id=c1_0.post_id
where
p1_0.id=?
'JPA > JPA 정리' 카테고리의 다른 글
@OneToOne 조회 (0) | 2024.08.25 |
---|---|
영속성 컨텍스트와 CRUD (0) | 2024.08.24 |