Member와 Team처럼 참조 관계로 엮여있을 경우 Member객체를 조회하면 조인 쿼리로 조회하여 Team객체까지 한 번에 찾아온다.

 

그런데 참조 관계로 엮여있기는 하지만 Team을 별로 사용하지 않는 비즈니스 로직일 경우에는 조인으로 Team까지 한 번에 가져오는 것이 낭비가 될 수 있다.

 

이를 막기 위해 프록시를 사용한 지연 로딩이 존재한다.

 

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @ManyToOne(fetch =  FetchType.LAZY)
    private Team team;
}

 

참조 관계 매핑 어노테이션의 fetch 속성을 통해 이를 조작할 수 있다.

즉시 로딩의 경우엔 Member를 조회하면 조인 쿼리로 Team까지 함께 가져온다.

(@ManyToOne, @OneToOne은 디폴트가 FetchType.EAGER으로 즉시 로딩이다.)

 

FetchType.LAZY를 사용할 경우 지연 로딩 방식을 사용하는데, 이 경우 조인 쿼리를 사용하지 않고 오롯이 Member객체만 조회한다.

이때 Member객체 안에 있는 Team 객체는 Team을 상속한 프록시 객체가 대체하게 된다.

(@OneToMany, @ManyToMany는 디폴트가 지연 로딩)

 

그러다가 m.getTeam.getName() 등으로 team객체의 기능을 직접 사용해야 하는 순간이 왔을 때 DB에 Team의 조회 쿼리를 날려 프록시 객체를 초기화해준다.

 

 

 

가급적 지연 로딩만 사용하는 것이 좋다.

엔티티들이 관계가 복잡해져 조인이 얽히고 섥힐수록 조인을 통해 한 번에 모든 객체를 조회하기 위한 낭비가 커진다.

 

기본적으로 설정은 LAZY로 해놓고 참조 객체들이 한  번에 필요한 경우에는 JPQL fetch join, 엔티티 그래프 등을 사용해서 한 번에 가져오도록 명시해주는 것이 좋다.

 

+ Recent posts