이번 포스팅은 즉시로딩과 지연로딩에 작성해보겠다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
Member 객체와 Team 객체가 서로 다대일 관계로 연관관계가 매핑되어 있다고 해보자
Member member = new Member();
member.setName("홍길동");
em.persist(member);
em.find(Member.class,1L);
단순히 Member 정보만 사용하는 로직일경우 Team과 연관관계 다대일 관계로 매핑되어 있어
Team 테이블의 정보까지 조인이 되어 가져오게 된다.
이렇게 되면 성능 저하가 발생한 문제점이 생긴다.
지연 로딩 LAZY를 사용해 프록시로 조회하면 된다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOnee(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
}
지연 로딩을 사용하면
Member member = em.find(Member.class, 1L);해서 조회할 때
Team 엔티티는 프록시(가짜)엔티티로 실제 엔티티를 상속 받아서 만들어진다.
프록시 객체는 실제 객체의 참조(target)를 보관하고 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출하게 된다.
Team team = member.getTeam();
team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회)
member엔티티에서 team 엔티티 정보를 조회할때 프록시 객체는 실제 엔티티를 호출하게 된다. 이때 영속성 컨텍스트에는 team 엔티티가 존재하지 않아 DB에서 조회를 하게 된다.
🧷 프록시 객체가 초기화를 할때 프록시 객체가 실제 엔티티로 바뀌는 것은 아님
즉시 로딩 EAGER을 사용해서 함께 조회한다.
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER) //**
@JoinColumn(name = "TEAM_ID")
private Team team;
}
즉시 로딩 EAGER는 member 조회시 항상 team도 같이 조회한다.
이때 지연 로딩과는 반대로 프록시 객체가 아닌 실제 엔티티가 조회된다.
연관관계가 매핑이 되어 있는 엔티티를 조회할 때 즉시 로딩과 지연 로딩이 존재한다.
엔티티를 분리해서 조회하고 싶은 경우 지연 로딩 LAZY로 설정하여 엔티티를 조회한다.
이때 실제 엔티티를 조회하는게 아니라 프록시 객체로 조회가 되며, 실제 엔티티를 사용하는 시점에 초기화(DB조회)를 한다.
함께 조회할 경우 EAGER로 설정하여 엔티티를 조회한다.
이때 JPA구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회하게 된다.