Java/JPA
프록시, 즉시로딩 주의
amungstudy
2023. 11. 17. 18:44
JPA에서는 ==비교 대신
instance of 사용하기~(프록시객체랑 그냥 객체 == 비교하면 false나옴)
(instanceOf 연산자는 객체가 어떤 클래스인지, 어떤 클래스를 상속받았는지 확인하는데 사용하는 연산자)
/* TRUE
Member m1 = em.find(Member.class, member1.getId());
Member m2 = em.find(Member.class, member2.getId());
System.out.println("m1 == m2" + (m1.getClass() == m2.getClass()));
*/
Member m1 = em.find(Member.class, member1.getId());
Member m2 = em.getReference(Member.class, member2.getId());
//false
System.out.println("m1 == m2" + (m1.getClass() == m2.getClass()));
System.out.println("m1 == m2" + (m1 instanceof Member)); // true
System.out.println("m1 == m2" + (m2 instanceof Member)); // true
영속성컨텍스트에 찾는 이미 엔티티가 있으면 getReference해도 엔티티로 가져옴
Member m1 = em.find(Member.class, member1.getId());
System.out.println("m1 = " + m1.getClass());
Member reference = em.getReference(Member.class, member1.getId());
System.out.println("reference = " + reference.getClass());
// JPA는 영속성 컨텍스트에 있고, PK가 같은 경우 == 비교하면 true를 보장해준다.
System.out.println("a == a:"+ (m1 == reference));
// JPA는 영속성 컨텍스트에 있고, PK가 같은 경우 == 비교하면 true를 보장해준다.
System.out.println("a == a:"+ (m1 == reference));
심지어 반대로 하면 ....프록시 가져옴
Member reference = em.getReference(Member.class, member1.getId());
System.out.println("reference = " + reference.getClass());
Member m1 = em.find(Member.class, member1.getId());
System.out.println("m1 = " + m1.getClass());
// JPA는 영속성 컨텍스트에 있고, PK가 같은 경우 == 비교하면 true를 보장해준다.
System.out.println("a == a:"+ (m1 == reference));
실무시 반드시 만나는 예외가 있다...
could not initialize proxy
준영속상태에서 프록시 접근시 발생.
실무에서는 즉시로딩 쓰면 안돼!
@ManyToOne, @OneToOne은 기본이 즉시로딩 -> LAZY로 설정하기
@ManyToOne(fetch = FetchType.LAZY)
즉시 로딩(EAGER) 적용하면 예상치 못한 SQL 발생함.
문제 회피 방법
1. @ManyToOne, @OneToOne은 기본이 즉시로딩 -> LAZY로 설정
2. fetch join이용
3. entitygraph
4. 배치 size