즉시로딩(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로 해야합니다.
