JPA 의 기초 Hibernate(2)

먹어보고·2023년 3월 31일
0

프록시
em.find() vs em.getReference()

em.find() : 데이터 베이스를 통해 실제 엔티티 객체 조회
em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회
가짜(프록시) 엔티티 객체 조회 : DB에는 쿼리가 실행되지 않고 값을 가져옴.

find()는 사용하자마자 쿼리를 통해 조회하여 데이터를 가져옴
getReference()는 사용 당시의 쿼리를 통해 조회를 하지 않고, 실제 값이 필요로 할때
조회되도록 설정

프록시 특징

  • 실제 클래스를 상속 받아서 생성

  • 실제 클래스와 겉 모양이 같다.

  • 사용자 입장에서 구분하지 않은채 사용할 수 있다.

  • 객체는 처음 사용할 때 한번만 초기화

  • 프록시 객체가 초기화 되어도, 실제 엔티티로 바뀌진 않고 실제 엔티티에 접근만 가능

  • 프록시 객체는 원본 엔티티를 상속받기 때문에 타입 체크 주의 ( == 비교 실패, 대신 instace of 로 사용)

  • 프록시와 객체는 항상 동일을 보장

  • 프록시 객체는 실제 객체의 참조(target)를 보관

    프록시 개체의 초기화
    사용자 데이터 요청 -> Proxy가 확인 -> Proxy는 가짜라서 값이 없음 -> 영속성 컨텍스트에 초기화 요청 -> 영속성 컨텍스트는 DB를 조회 -> 영속성 컨텍스트가 실제 Entity 생성 -> 사용자가 요청한 데이터 표출

    지연로딩 과 즉시로딩
    지연로딩 : 프록시를 사용하여 실제로 객체가 사용될 때 SQL
    즉시로딩 : 애초부터 SQL를 실행하여 데이터 가져옴

    프록시와 즉시로딩

  • 실무에서는 즉시로딩 사용 X (가급적 지연 로딩)

  • JPQL에서 N+1 문제를 일으킴

  • @ManyToOne, @OneToOne은 기본이 즉시로딩 -> LAZY로 변경필요

  • 무조건 지연 로딩만 쓰세요

0개의 댓글