[JPA 기본] 07 - 프록시

heyhey·2023년 3월 6일
0

JPA

목록 보기
6/7

프록시를 왜 사용할까?
상황을 먼저 살펴보자.
Member는 Team 소속이다 그렇다고 Member를 조회할때 Team의 모든 것을 조회하는 것이 효율적일까?
프록시는 Member를 조회했을때 Team을 바로 조회하는 것이 아닌 그 값이 필요할 때, 조회를 한다.

프록시 기초


em.getReference

em.find 와 비슷하지만 다르다.

  • em.find() : 데이터베이스를 통해 실제 엔티티 객체 조회
  • em.getReference() : 데이터 베이스 조회를 미루는 가짜(proxy) 엔티티 조회

프록시의 특징

  • 실제 클래스를 상속받아 만든다.

  • 실제 클래스와 겉모습은 같다.

  • 사용하는 입장에서는 진짜 객체인지 프록시인지 구분하지 않고 사용해도 된다.

  • 프록시 객체는 실제 객체의 참조 를 보관한다.

  • 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드를 호출한다.

  • 프록시 객체는 처음 사용할 때 한번만 초기화 한다.

  • 프록시 객체를 초기화할 때, 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다.
    초기화되면 프록시 객체를 통해 실제 엔티티에 '접근'이 가능하다.

  • 프록시 객체는 원본 엔티티를 상속받기 때문에, 타입을 == 으로 비교하면 안되고 instance of를 사용한다.

  • 영속성 컨텍스트에 찾는 엔티티가 존재하면, 실제 엔티티를 반환한다.

즉시 로딩과 지연로딩

프록시를 사용해서 할 수 있는 것이 뭐가 있을까?
아니 프록시를 왜,어떻게 사용할까? 라고 하면 지연로딩을 사용하기 위해서 라고 얘기할 수 있을 것 같다.
=> 지연 로딩 LAZY를 사용해서 프록시로 조회한다.

사용법

@ManyToOne(fetch = Fetchtype.LAZY)
@JoinColumn(name="TEAM_ID")
private Team team;

이렇게 LAZY 로딩으로 사용하게 되면, 실제 team을 사용하는 시점에 초기화(DB 조회)가 된다.

EAGER

반대로 Member와 Team을 자주 함께 사용할때는 이거를 사용하면 된다.

EAGER를 사용하면 Member 조회시 Team도 항상 조회하게 된다.

하지만 EAGER를 사용하게 되면 예상치 못한 SQL이 사용되기 때문에 N+1 문제를 일으킨다.
그래서 그냥 가급적 지연 로딩만 사용하는 것이 좋다고 한다.

지연로딩으로 변환하자!

@OneToMany , @ManyToMany 는 기본이 지연로딩이라 괜찮지만
@ManyToOne,@OneToOne 은 기본이 즉시로딩이라 LAZY로 변환해서 사용해야 한다.

영속성 전이 (CASCADE)

특정 엔티티를 영속 상태로 만들 때, 연관된 엔티티도 함께 영속 상태로 만들고 싶을 때 사용한다.

사용법

@OneToMany(mapped="parent",cascade= CascadeType.PERSIST)

고아 객체

부모 엔티티와 연관관계가 끊어진 자식 엔티티를 자동으로 삭제한다.
참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능

  • 참조하는 곳이 하나일 때 사용해야 한다.
  • 특정 엔티티가 개인 소유일 때 사용한다.

사용법

@OneToOne,@OneToMany 일 때 사용한다.

@OneToMany(mapped="parent",cascade= CascadeType.ALL,orphanRemoval=true)

두 옵션 모두 활성화하면 부모 엔티티를 통해서 자식의 생명주기를 관리할 수 있다.

도메인 주도 설계의 Aggreate Root 개념? 을 구현할 때 유용하다고 한다.

profile
주경야독

0개의 댓글