728x90
- 글을 이해하기 위한 지식 - 영속성 컨텍스트
실제로 잘 안 쓰이기는 개념이기는 하지만 나중에 지연 로딩을 위해 알아본다.
예를 들어 Member Entity안에 Name, Team 필드가 있는데
Member의 Name을 조회할 때 굳이 Team도 함께 조회해야 할까?
즉 member객체를 전체 가져오고 그 안에서 member.getTeam()을 꼭 해야 할까?
아니다 꼭 다 가져올 필요는 없다 이걸 프록시로 해결한다.
프록시 기초
- 데이터베이스 조회를 미루는 가짜 엔티티 객체
em.getReference를 사용하면 호출한 시점에는 쿼리가 안 나가고(member 객체 전체를 불러오지 않고) 사용되는 시점(em.getUserName)에 쿼리가 나간다.
실제 클래스를 상속받아서 만들어지며 프락시 객체는 실제 객체의 참조(target)를 보관한다.
- 사용자가 getName()을 요청하면
- Mmeber target값이 없으니 영속성 컨텍스트에 요청(초기화 요청)
- 실제 객체를 생성해서 주면
- 실제 객체를 target과 연결함.
Member member = em.getReference(Member.class,member1.getId()); // 아직 프록시만 만들어짐
refMember.getUsername(); //프록시 안에 실제 객체가 들어감
프록시의 특징
- 프록시 객체는 처음 사용할 때 한번만 초기화
- 프록시 객체를 초기화 할 때 프록시 객체가 실제 엔티티로 바뀌는 것이 아님.
- 프록시로 넘어올지 엔티티로 넘어올지 모르기에 == 비교로 하지 말기
- 영속성 컨텍스트에 이미 찾는 엔티티가 있으면 em.getReference해도 객체가 들어옴
- 프록시를 한번 반환하면 그 이후에 find해도 프록시를 반환하게 됨.
- 프록시가 아니든 프록시든 문제가 없게 개발하는 것이 중요함.
그런데 만약 초기화해야 하는 영속성 콘텍스트가 없는 상황이 돼버리면?
error - og.hibernaete.LazyInitiaizationException
고로 프록시를 사용하려면 영속성 컨텍스트 꼭 있어야 함.
프록시 확인
초기화 여부 확인
- 프록시 인스턴스 초기화 여부 확인
PersistenceUnitUtil.isLoaded(Object entity)
- 프록시 클래스 확인 방법
entity.getClass().getName()
- 프록시 강제 초기화(하이버네이트 제공)
org.hibernate.Hibernate.initialize(entity);
(참고) JPA 표준은 강제 초기화 없음 member.getName()으로 초기화해야 함
출처 - 인프런 김영한 JPA 기본 강의
728x90
'JPA' 카테고리의 다른 글
연관관계에 관한 다양한 생각들(+지양해야할것) (0) | 2022.11.17 |
---|---|
[JPA] 값 타입과 불변 객체 (0) | 2022.08.02 |
[JPA] 지연 로딩(Lazy Loading) (0) | 2022.07.29 |