java jpa 공부중
Member의 속성만을 조회할 때 Team의 내용까지 조회를 해야할까? 아니오.
em.find() : DB를 통해서 실제 엔티티 객체 조회
em.getReference() : DB조회를 미루는 가짜(프록시) 엔티티 객체 조회.
: DB에 쿼리가 안나갔는데 쿼리가 조회가 되는..?
em.find()를 하면 DB에 쿼리를 날려 값을 가져오지만 em.getReference()의 경우 메소드가 실행될 때는 DB에 쿼리를 날리지 않는다.
프록시 객체는 처음 사용할 때 한 번만 초기화
프록시 객체를 초기화 할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아님. 초기화되면 프록시 객체를 통해서 실제 엔티티 접근이 가능
프록시 객체는 원본 엔티티를 상속받음. 따라서 타입 체크시 주의해야함( == 비교 X, 대신 instance of 사용)
영속성 컨텍스트에 찾는 엔티티가 이미 있으면 em.getReference()를 호출해도 실제 엔티티 반환
영속성 컨텍스트의 도움을 받을 수 없는 준영속 상태일 때, 프록시를 초기화하면 문제 발생 (하이버네이트는 org.hibernate.LazyInitializationException 예를 터트림)
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY) //LAZY 로딩
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
Member member = em.find(Member.class, 1L);
Team team = member.getTeam();
team.getName(); //실제 team을 사용하는 시점에 초기화(DI)
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.EAGER) //즉시로딩
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
Member member = em.find(Member.class, 1L);
Team team = member.getTeam();
team.getName(); //em.find()로 조회할 때부터 한번에 조회됨
public class Parent {
...
@OneToMany(mappedBy= "parent", cascade= CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
...
}
@OneToMany(orphanRemoval = true) //하면
Parent parent1 = em.find(Parent.class, id);
parent1.getChildren().remove(0);// 자식 엔티티를 컬렉션에서 제거