프록시
em.find() : 데이터베이스를 통해서 실제 엔티티 객체 조회
em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
Member findMember = em.getReference(Member.class, member.getId());
System.out.println(findMember.getId() + " / " + findMember.getName());
초기화 과정 이후엔 DB 접근 없이 데이터를 가져올 수 있다
System.out.println("isLoaded = " + emf.getPersistenceUnitUtil().isLoaded(findMember));
System.out.println(findMember.getClass());
Hibernate.initialize(findMember);
즉시 로딩과 지연 로딩
지연로딩으로 세팅하면 연관된 걸 프록시로 가지고옴
public class Member extends BaseEntity{
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
member 객체를 가져올 때 team까지 같이 가져옴
public class Member extends BaseEntity{
@Id @GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "TEAM_ID")
private Team team;
List<Member> members = em.createQuery("select m from Member", Member.class).getResultList();
// member 쿼리 하나, team 쿼리 하나 총 두번 돔
em.find는 pk를 찍어서 가져오기 때문에 JPA가 내부적으로 최적화 할 수 있지만 JPQL은 그대로 SQL로 번역이 됨
즉시로딩은 무조건 값이 들어가있어야 하기 때문에 별도로 팀을 가져오기 위한 쿼리가 실행됨
영속성 전이(CASCADE)
특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때
Parent
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
private List<Child> childList = new ArrayList<>();
Child
@Entity
public class Child {
@Id @GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
CASCADE를 걸어주면 parent 엔티티만 저장해도 child까지 저장됨
고아객체
@Entity
public class Parent {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Child> childList = new ArrayList<>();
Parent findParent = em.find(Parent.class, parent.getId());
findParent.getChildList().remove(0);
// 자식 엔티티를 컬렉션에서 제거