프록시
지연로딩을 하기 위해서 jpa 내부적으로 껍데기 객체를 만들어야 한다.
이 껍데기 객체를 프록시 객체라고 한다.
프록시클래스는 실제클래스를 상속받아서 만들어지므로 실제 클래스와 겉모습이 같다
따라서 사용자 입장에서 이게 프록시인지, 실제클래스인지 구분하지 않아도 된다.
프록시객체 특징
- 처음 사용할때 한번만 초기화
- 프록시 객체를 초기화 한다고 해서 프록시객체가 실제객체가 되는게 아니고
실제객체를 만들고, 프록시객체에서는 실제객체에 대한 참조를 하게된다.
즉, 프록시객체를 통해서 실제객체에 접근하여 값을 가져온다 ㅎ
-프록시객체는 원본 엔티티를 상속받은 객체이므로 타입체크시 ==을 지양하고
Instance of 를 쓰자
- getreference를 쓰면 프록시객체를 가져올 수 있다
- 초기화는 영속성 컨텍스트의 도움을 받아야 가능하다
만약 영속성 컨텍스트와 연결되지 않았는데 초기화를 하게되면
하이버네이트에서는 lazyinitalizationexception 예외를 발생시킴
+
하나의 영속성컨텍스트 (하나의 트랜잭션안에서)에서
관리되는 객체들은 참조값이 동일하도록 관리를 한다.
실제로 가져오고 = 동일한 객체를 프록시를 가져오고
무조건 동일 레퍼런스로 가져와야 한다.
- 프록시 가져오기 (프록시)
- Find 로 가져오기 (실제? 프록시?)
-> 다르게 가져와서 가져오는 이점이 없기 때문에 ㅎ…
지연로딩
패치타입을 lazy 하면 해당 부분을 지연로딩 처리하며
프록시타입으로 받아온다!
실제 값을 사용하는 시점에 객체를 초기화한다. (getClass는 아님)
-> 근데 값을 계속 같이 쓰는 경우엔 지연로딩은 오히려 악!
-> 그럴땐 즉시로딩을 하자
즉시로딩(그냥 쓰지마라. 테이블 2-3개가 아니면 ㅋ)
패치타입을 eager를 사용해서 조회
Jpa 구연체는 왠만하면 조인쿼리로 한번에 가져온다.
즉시로딩 주의…
1.예상치못한 sql 발생 (조인이 많으면 헤비 해짐)
2.jpql로 일부 객체만 조회했는데, 즉시로딩이라 다시 또 전체객체 조회쿼리가 발생..
실무에서 즉시로딩을 써야한다면…
-일단 지연로딩으로 다 깐다.
-그다음 즉시로딩이 필요한 부분에 패치조인을 사용한다.
-어노테이션, 배치사이즈
-다대일, 일대일은 기본이 즉시로딩인데 지연로딩으로 변경해야한다.
지연로딩의 활용
영속성 전이 (cascade)
부모 저장할때 그냥 관련있는 자식도 저장하고 싶을때.
개발자 편의성 측면 그 이상 그 이하도 아님
주의할 점은 자식을 관리하는 주체가 연관된 부모만일 경우
부모와 자식의 생명주기가 동일할때
고아객체
부모로 부터 연관관계가 끊겨진 객체를 자동으로 db에서 삭제
이것 또한 참조가 하나인곳에서 사용해야함..(특정엔티티가 개인소유일 때)
또 부모를 제거하면, 자식도 제거 됨(케스케이드처럼 동작함)
영속성 전이 + 고아객체
두 옵션을 모두 사용하면, 부모의 생명주기를 통해 자식의 생명주기를 컨트롤 할 수 있음
'프로그래밍 > JPA' 카테고리의 다른 글
7장 고급매핑을 읽으면서.... (0) | 2023.10.05 |
---|---|
6장. 다양한 연관관계 매핑 (0) | 2023.09.18 |
3장. 영속성 관리 (0) | 2023.08.30 |
2장 JPA 시작 (0) | 2023.08.21 |
1장. JPA소개 (0) | 2023.08.21 |
댓글