본문 바로가기
학습

[Java] JPA 강의 - 8 (프록시와 연관관계 관리)

by 공덕뉸나 2024. 2. 15.

프록시

프록시 기초

- em.find() : 데이터베이스를 통해서 실제 엔티티 객체를 조회하는 것

- em.getReference() : 가짜(프록시) 엔티티 객체를 조회하는 것 -> 실제 사용되는 시점에 쿼리가 실행됨

 

프록시 특징

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

--> 프록시 객체를 통해 실제 entity에 접근

- 영속성 컨텍스트에 엔티티가 있으면 getReference 호출해도 실제 엔티티 반환

--> 하나의 영속성 컨텍스트에 있고 PK가 동일하면 JPA는 객체 비교시 TRUE를 반환함

- type 체크시 -> == 비교가 아닌 instance of 사용하기

- 준영속 상태일 때, 프록시를 초기화하면 에러 발생함 (initializeException)

 

즉시 로딩과 지연 로딩

"지연 로딩"

fetch = FetchType.LAZY 

- 실제 속성을 사용할 때 프록시 초기화, DB에서 값을 가져옴

 

"즉시 로딩"

- JPA 구현체는 가능하면 조인을 사용해서 한 번에 함께 조회

- 실무에서는 가급적 지연 로딩 사용하기

- 즉시 로딩은 JPQL에서 N+1 문제를 일으킴 (추가 쿼리가 나감)

- @ManyToOne, @OneToOne은 기본이 즉시 로딩이므로 LAZY로 설정하여 사용하기

 

영속성 전이 : CASCADE

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

ex) 부모 엔티티 저장할 때 자식 엔티티도 함께 저장 (연쇄)

- 하나의 parent와 child가 연관있을 때만 사용

(소유자가 하나일 때, 단일 에티티에 종속적일 때)

 

종류

- ALL : 모두 적용

- PERSIST : 영속

- REMOVE : 삭제

- MERGE : 병합

- REFRESH 

- DETACH

 

고아 객체

- orphanRemoval = true

- 참조하는 곳이 하나일 때 사용해야함

- 특정 엔티티가 개인 소유할 때 사용

- 고아 객체 제거 기능을 활성화 하면, 부모를 제거할 때 자식도 함께 제거됨

( = CascadeType.REMOVE 처럼 동작함)

 

영속성 전이 + 고아 객체, 생명주기

- CascadeType.ALL + orphanRemoval = true

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