다음과 같은 엔티티 관계가 있다고 하자
Member : Team = N : 1
Member Entity
@Getter
@Setter
@Entity
public class Member {
@Column(name = "memberName")
private String memberName;
@ManyToOne
@JoinColumn(name = "teamId")
private Team team;
}
Team Entity
@Getter
@Setter
@Entity
public class Team {
@Column(name = "teamId")
private String teamId;
}
즉시 로딩 : 엔티티 조회 시 연관된 엔티티도 함께 조회.
@ManyToOne(fetch = FetchType.EAGER) // 또는 defualt 설정이다
@JoinColumn(name = "teamId")
private Team team;
즉, Member member = em.find(Member.class, "member1") ; 을 실행하게 되면
member에 매핑된 Team도 함께 조회 된다.(즉시 로딩을 최적화 하기 위해여 가능하면 조인쿼리가 날아간다)
member 1 로딩과 동시에 team1도 즉시 로딩(Eager)
지연 로딩 : 엔티티를 실제 사용 할때 조회.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "teamId")
private Team team;
Member member = em.find(Member.class, "member1") ; 을 실행하게 되면
member 정보만 로딩하고, member에 매핑된 team의 정보는 로딩하지 않는다. 대신 프록시 객체를 넣어둔다.
Team team = member.getTeam(); 을 통해서 반환되는 프록시 객체는 실제 사용될 때까지 데이타 로딩을 미룬다.
team.getName(); 등과 같이 실제로 사용는 구문이 나오면 DB select 쿼리가 날아가서 프록시 객체를 초기화 한다.
JPA의 기본 Fetch 전략은 다음과 같다.
@ManyToOne, @OneToOne : FetchType.EAGER
@OneToMany, @ManyToMany : FetchType.LAZY
처음부터 연관된 엔티티들을 모두 영속성 컨텍스트에 올려두는 것은 비효율 적이다. 그렇다고해서 필요할때마다 sql 을 실행하는 것도 최적화 측면에서 좋지 않다.
애플리케이션의 성향에 따라 즉시로딩 또는 지연로딩을 알맞게 사용하는 것이 좋다.
읽고 있는 JPA책에서는 우선 모든 Fetch를 Lazy로 수행하며, 애플리케이션의 상황을보며 EAGER로 전환할 수 있는 부분을 찾는게 좋을 것이라고 한다.
'Development > DB, JPA' 카테고리의 다른 글
Persistence Context 영속성 컨텍스트 (0) | 2017.03.12 |
---|---|
트랜잭션, 트랜잭션 격리수준(Isolation Level) (0) | 2016.12.30 |
@MappedSuperclass 에 관하여 ... (0) | 2016.08.10 |
Lazy Exception 과 Hibernate.initialize() (0) | 2016.07.26 |
CASCADE, 영속성 전이 (0) | 2016.07.17 |