기존의 조회하는 기능을 사용하면 select 쿼리가 바로 나갔다. 하지만 getReference() 로 호출하면 쿼리가 안나가고 생성된 엔티티를 사용할 시(getName()) 에 select 쿼리가 나간다. 쿼리가 지연되는 상황이 보여진다. 이게 어떻게 동작이 되는 걸까?
먼저 프록시 객체라는 것을 알아야 한다. 하이버네이트가 만들어주는 프록시 객체는 Entity 타입의 target 참조변수가 존재 한다.
이 객체를 사용시에 영속성 컨텍스트에 초기화를 요청하고 영속성 컨텍스트는 DB에 원본 엔티티를 조회하고 생성 한다.
다음으로 프록시 객체가 원본 엔티티를 생성하여 getName() 로 호출 하여 사용한다.
위의 내용을 그림으로 보면 이해할 것이다.
프록시 객체의 특징을 살펴보자
- 프록시 객체는 처음 사용할 때 한번만 초기화한다.
- 프록시 객체가 실제 엔티티로 바뀌는 것이 아니고 프록시 객체를 통해 접근이 가능해지는 것이다.
- 프록시 객체는 원본 엔티티를 상속받아 타입 체크시 instanceof 연산자로 체크해야한다.
- 영속성 컨텍스트에 찾는 엔티티가 있는 경우 getReference()를 사용해도 실제 엔티티를 반환한다.
- 준영속 상태일 때 프록시를 초기화 하면 에러가 발생한다.
프록시 확인
- 초기화 여부 확인
emf.getPersistenceUnitUtil().isLoaded(Object entity);
- 강제 초기화
Hibernate.initialize(entity);
- 클랙스 확인
entity.getClass();
강제 호출 : getName();
'JPA' 카테고리의 다른 글
[Jpa] Deprecated 된 getById() 대안 getReferenceById() (0) | 2022.08.02 |
---|---|
[Jpa] Dirty Checking (0) | 2022.07.19 |
[Jpa] Projections (0) | 2022.07.18 |
[Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까? (1) | 2022.05.18 |
[Spring JPA] CASCADE 는 무엇일까? (0) | 2022.05.15 |
[Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까? (0) | 2022.05.15 |
[Spring JPA] 객체지향의 상속관계 매핑은 어떤 전략을 사용할까? (0) | 2022.05.12 |
[Spring JPA] 객체의 연관관계는 어떻게 관계를 맺는것이 좋을까? (0) | 2022.05.10 |