JAVA17, Spring Boot 3.2.2, Mysql 8.3.0 을 기준으로 수행을 하겠다.
Practice 깃허브 주소


- Team와 Member 엔티티가 일대N 관계를 가지고 있고 다음과 같이 데이터를 가지고 있다.
Fetch Eager (즉시 로딩)



- @ManyToOne에서 즉시 로딩으로 설정하고 멤버 엔티티에서 팀 이름을 가져오면,

- 이렇게 member와 team의 join문이 나가고, 팀이름까지 출력이 된다.
findMember.getTeam().getClass() 은 Entity Team이 출력되었다.
Fetch Lazy (지연 로딩)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id", nullable = false)
private Team team;

- ManyToOne을 Lazy로 변경하고 다시 한번 테스트 코드를 실행 해보면 member만 조회를 하고, LazyInitializationException이 발생한다.
findMember.getTeam().getClass() 도 Entity Team이 아니라 Team$HibernateProxy$1O7tRvC9 이렇게 Proxy 객체가 나왔다.
🧐왜 그런가?

- JPA에서는 Proxy 객체에 있는 실제 객체 참조를 통해 객체를 가져온다.
- 처음에 초기화 요청을 한 번 하는데 영속성 컨텍스트에 없으면 DB 조회를 해가지고 보관한다.
- 즉시로딩을 하면 join문을 통해서 Team 객체 까지 가져옴으로 team 이름을 출력할 수 있었다. 그러나 지연로딩을 하면 member 객체만 가져오는데 Team 객체는 영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하므로 예외가 발생하는 것이다. → 즉 프록시 객체로 가져온다.
정리
- 지연 로딩 : JPA에서 데이터를 조회할 때 연관된 데이터를 필요할 때 가져오는 것
- 즉시 로딩 : JPA에서 데이터를 조회할 때 연관된 데이터까지 한 번에 가져오는 것