즉시로딩(Eager)과 지연로딩(Lazy)
예제로 이해하기
데이터베이스의 사용자 테이블(User)
id | username | password | |
1 | ssar | 1234 | ssar@nate.com |
2 | sai | 1234 | sai@naver.com |
데이터베이스의 게시글 테이블(Board)
id | title | content | userId |
1 | 제목1 | 내용1 | 1 |
2 | 제목2 | 내용2 | 2 |
3 | 제목3 | 내용3 | 2 |
영속성 컨텍스트에 저장된 게시글 객체
public class Board {
private int id;
private String title;
private String content;
private User user;
}
데이터베이스의 데이터를 가지고 게시글 모델을 만들 때 데이터베이스의 게시글 테이블과와 영속성 컨텍스트의 자바 오브젝트에 모순이 생겨 매핑 시 문제가 생긴다. 여기서 @ManyToOne 어노테이션을 걸어주면 이 문제를 해결할 수 있다. 영속성 컨텍스트는 데이터를 동기화하려고 하기 때문에 모순된 데이터(userId)가 들어오면 이를 Primary key로 인식하여 사용자 테이블에서 데이터를 조인하여 가지고 온다. 이는 @ManyToOne의 기본 전략이 Eager이기 때문인데 Lazy 전략으로 바꿔주면 모순된 데이터는 무시하고 나머지 데이터를 가지고 온다. Lazy 전략은 요청시 데이터베이스에서 데이터를 동기화해서 가져오게 된다. 즉 필요할 때 데이터를 동기화한다.
<Eager 전략>
<Lazy 전략>
사용하는 방법
package com.cos.blogapp.domain.board; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.Table; import com.cos.blogapp.domain.user.User; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Table(name = "board") @AllArgsConstructor @NoArgsConstructor @Data @Entity public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; //PK (자동증가 번호) @Column(nullable = false, length = 70) private String title; // 아이디 @Lob private String content; @JoinColumn(name = "userId") @ManyToOne(fetch = FetchType.EAGER) private User user; }
기본 전략
@ManyToOne : Eager
@OneToMany : Lazy
옵션을 추가해서 전략 지정 가능
fetch = FetchType.LAZY
fetch = FetchType.EAGER
만약 조인이 필요없는 페이지(게시글 데이터만 가져오는 경우)에서 Eager 전략을 쓰면 연산이 많이 일어나기 때문에 Lazy 전략을 쓰는 것이 좋다.
opne-in-view 설정
jpa: open-in-view: true hibernate: ddl-auto: none naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl show-sql: true
false
트렌젝션이 종료될 때 데이터베이스 커넥션이 끊긴다. Lazy 전략은 응답하기 직전에 동기화되기 때문에 적절하지 않다.
true
데이터베이스 쿼리가 뷰를 렌더링하기 직전까지 데이터베이스 커넥션이 유지된다.
Lazy전략은 open-in-view 기본 설정을 true로 해야합니다.