Fetch Type은 하나의 Entity를 조회할 때 연관관계에 있는 객체를 어떻게 가져올지 설정을 하는 것입니다.
Fetch Type을 설정할 때는 Eager와 Lazy 중에서 선택을 할 수 있습니다.
Eager로 설정을 하면 연관관계에 있는 Entity를 미리 다 가져오는 것입니다.
Lazy는 연관관계에 있는 Entity를 사용할 때 가져오는 것입니다.
OneToOne, ManyToOne과 같이 One으로 끝나는 관계는 기본값이 EAGER이고, OneToMany, ManyToMany처럼 Many로 끝나는 관계는 기본값이 LAZY입니다.
User 클래스를 수정해줍니다.
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
현재 콘솔창에 찍히는 SQL이 한 줄로 쭉 나오기 때문에 보기 불편합니다. 이를 해결하기 위해서는 application.properties에 아래 코드를 추가해줍니다.
spring.jpa.properties.hibernate.format_sql=true
연관 관계에서 발생하는 문제로 연관 관계가 설정된 entity를 조회할 경우에 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오게 된다.
UserApiController 수정
@GetMapping("/users")
List<User> all() {
List<User> users = repository.findAll();
return users;
}
application.properties에 로그를 위한 코드를 추가해줍니다.
logging.level.org.project=DEBUG
@Slf4j 어노테이션을 추가해주고 log.debug로 확인해줍니다.
@GetMapping("/users")
List<User> all() {
List<User> users = repository.findAll();
log.debug("getBoards().size() 호출전");
log.debug("getBoards().size() : {}", users.get(0).getBoards().size());
log.debug("getBoards().size() 호출후");
return users;
}
지금 데이터를 따로 가지고 오기 때문에 이것을 조인으로 처리하기 위해 @EntityGraph를 사용해줍니다.
UserRepository에서 아래 코드를 추가해줍니다.
@EntityGraph(attributePaths = {"boards"})
List<User> findAll();
@EntityGraph -> 연관관계가 Lazy로 지정 되어있을 경우 fetch 조인을 사용하여 여러 번의 쿼리를 한 번에 해결할 수 있습니다.
postman에서 이와 같이 Get 요청을 하게 되면
조인으로 처리가 된 것을 확인할 수 있습니다.