em.find() vs em.getReference()
1. em.find() 데이터베이스를 통해서 실제 엔티티 객체 조회
2. em.getReference() 데이터베이스 조회를 미루는 가짜(프록시)엔티티 객체 조회 (쿼리 안나감)
프록시 특징
Member m1 =. em.find(Member.colss, member1.grtId());
Member m2 =. em.getReference(Member.colss, member2.grtId());
System.out.println("m1 == m2 : "+ (m1 == m2)); --> false
System.out.println("m1 == m2 : "+ (m1 instanceof Member)) --> true
System.out.println("m1 == m2 : "+ (m2 instanceof Member)) --> true
Member member1 = new Member();
member1.setUsername("member1");
em.persist(member1);
em.flush();
emn.clera();
Member m1 =. em.find(Member.colss, member1.grtId());
System.out.println("m1 = "+ m1.getClass());
//영속성 컨텍스트에 올라가있다. 이 상태에서
Member refer = em.getReference(Member.class, member1.getId());
System.out.println("refer = " + refer.getClss());
//결과는 다음과 같이 나온다.
m1 = class hellojpa.Member
refer = class hellojpa.Member
!! 왜 refer역시 Member가 나오는걸까? (프록시가 아닌)
JPA는 하나의 Transaction안에서의 같은것에 대한 보장을 해준다.
프록시에서 가져오더라도 JPA에서는 == 비교시 true보장해주는 속성이 있다. 이미 영속성 컨텍스트에 존제하는경우는 다음과같은 결과를 만든다.
Member member1 = new Member();
member1.setUsername("member1");
em.persist(member1);
em.flush();
emn.clera();
Member refMember = em.getReference(Member.class, member1.getId());
System.out.println("refMember = " + refMember.getClass()): //Proxy
em.detach(refMember); // 만약에 영속성 컨텍스트에서 꺼낸다면?
em.clear(); // 영속성 컨텍스트를 다 비워버린다면?
refMember.getUsername(); // 프록시를 초기화 할 수 없게된다.
emf.PersistenceUnitUtil().isLoaded()
System.out.println(refMember = " + refMember.getClss().getName())
Hibernate.initialize(refMember);
프록시를 이해해야 즉시로딩과 지연로딩에 대한 이해를 할 수 있기 떄문에 이해가 필요하다.