🥕
TIL
  • [TIL] Studying tech / computer science knowledge
  • KeyMap
  • 알고리즘
    • 복잡도 계산 ( Computational Complexity )
    • DisjointSet-unionFind
    • Bellman-ford Algorithm
    • Dijkstra's Algorithm
    • DP ( Dynamic Programming , 동적 계획법 )
    • 플로이드-워셜 알고리즘 (Floyd-Warshall algorithm)
    • Kruskal's Algorithm
    • 최장 증가 수열 (Longes Increasing Subsequence)
    • Prim's Algorithm
    • 정렬
    • 시간복잡도 와 공간복잡도 ( Time Complexity & Space Complexity )
    • Topological Sort (위상 정렬)
  • 책 읽고난 후 요약
    • 프로그래밍 대회에서 배우는 알고리즘 문제해결 전략
    • cleancode
    • 도메인 주도 설계로 시작하는 마이크로서비스 개발
    • 오브젝트
  • CDC
    • debzium
    • kafka
  • 개발 상식
    • asciidoctor
    • 컴파일러
    • ELK 스택
    • 엔디안
    • git
    • Gitmoji
    • 테스트 종류
    • 라이브러리와 프레임워크
    • 정규 표현식
    • REST API
    • 동기와 비동기 / Blocking과 NonBlocking
    • Transaction Script와 Domain Model
    • 디자인 패턴
      • 행동 패턴
      • 객체 생성 패턴
        • 추상 팩토리 패턴
        • 빌더 패턴
        • 팩토리 메서드 패턴
        • [생성 패턴] 프로토 타입 (Prototype Parttern)
        • 싱글톤
      • 구조 패턴
        • 어댑터 패턴
        • 브릿지 패턴
        • 컴포짓(Composite) 패턴
        • 데코레이터
        • 프록시
    • refactoring
      • 중복 코드
      • 전역 데이터
      • 긴 함수
      • 긴 매개변수 목록
      • 가변 데이터
      • 이해하기 힘든 이름
  • 자료구조
    • AVL Tree
    • Splay Tree
    • aaTree
    • array-list
    • 자료구조 시간/공간 복잡도
    • 그래프
    • 힙
    • Red Black Tree
    • stack-queue
    • 트리 ( Tree )
  • DevOps
    • MSA
    • Kubernetes
      • AccessingAPI
      • controller
      • dashboard
      • kubernetes
      • object
      • pod
      • service
      • volume
  • Java
    • 어노테이션
    • 제어문
    • 데이터 타입
    • Enum
    • jvm
    • 연산자
    • thread
    • Java8
      • CompletableFuture
      • Date/Time
      • 어노테이션과 메타스페이스
      • 인터페이스
      • 람다식
      • Optional
      • 스트림
  • JavaScript
    • moduleProject
    • webpack-babel
    • 코어 자바스크립트
      • array
      • 함수 바인딩
      • 데코레이터와 포워딩
      • Class
      • 비교 연산자
      • Date 내장 객체
      • destructuring-assignment
      • function
      • 함수의 prototype 프로퍼티
      • 가비지 컬렉션 ( Garbage Collection )
      • JSON (JavaScript Object Notation)
      • map-set
      • 내장 프로토타입
      • new연산자와 생성자 함수
      • 객체
      • Object.keys, values, entries
      • 옵셔널 체이닝 '?.'
      • 프로퍼티 플래그
      • 프로퍼티 종류
      • 프로토 타입
      • 호출 스케줄링 ( scheduling a call )
      • scope
      • this
      • type-conversions
      • type
      • 함수의 자료형
      • var_let_const
  • Linux
    • 기본 명령어
    • 파일 종류
    • 리눅스
  • 네트워크
    • 응용 계층 ( Application Layer )
    • 오류 검출과 오류 정정
    • Http
    • Http Header
    • 컴퓨터 네트워크란
    • 네트워크 계층
    • 네트워크 제어 영역
    • 전송 계층 ( Transport Layer )
  • PHP
    • Facade
    • composer
    • scopeResolutionOperator
    • Laravel
      • SocialProvider
      • architecture
      • blade
      • controller
      • db
      • dbArchitecture
      • debug
      • eloquent
      • email
      • event
      • exceptionHandling
      • middleware
      • model
      • modelFactory
      • pagingLoading
      • queryBuilder
      • route
      • scout
      • seeding
      • tntsearch
      • validate
      • view
  • React
    • Next.js
    • React 란?
  • Spring
    • Controller
    • 요청이 들어왔을때 스프링이 처리하는 방법 ( 내부구조 )
    • ConfigurationProperties
    • Entity / DTO / VO
    • Maven
    • Repository와 DAO
    • 스프링 빈
    • Spring Framework
    • MVC 패턴
    • 도메인 입력값 검증
    • Spring Cloud
      • Spring Cloud
      • Eureka
    • Spring Data
      • JPA
      • JPA 어노테이션
      • 엔티티 비교
      • 복합 키와 식별 관계 매핑
      • JPA 예외처리
      • 객체지향 쿼리
      • EntityManagerFactory와 EntityManager
      • JPA 최적화
      • 프록시와 연관관계 맵핑
      • 연관관계
      • 상속관계 맵핑
      • 트랜잭션 범위와 영속성 컨텍스트
      • 데이터 타입
      • MySQL 연결
      • Pageable
    • Spring Project들과 library
      • Custom Serialize
      • Elasticsearch Index API
      • Spring HATEOAS
      • lombok (롬복)
      • Model Mapper
      • Object Mapper
      • Representation Model
      • Spring REST Docs
      • Spring Boot
    • Spring Security
      • Spring Security
      • Authentication
      • Authentication Filter
      • Authorization Filter
      • Filter Chain
      • SecurityContext
      • Spring OAuth2.0
    • Spring Test
      • AssertJ
      • Junit5
      • JunitParams
      • Mock Object
  • DataBase
    • ALIAS
    • CONCAT
    • CTE
    • Group By
    • HAVING
    • IFNULL
    • 인덱스
    • JOIN
    • ORDER BY
    • ROLLUP
    • SELECT
    • SELECT DISTINCT
    • SQL
    • WHERE
  • Web 상식
    • OAuth
    • WAS
    • HTTP통신 기반 인증
    • 브라우저
    • CSR 과 SSR
    • HTTPS
    • Web
Powered by GitBook
On this page
  • ◾ 사용 방법
  • ◾ 특징
  • ◾ isLoaded()
  • 즉시로딩과 지연로딩
  • ◾ 기본 전략
  • 영속성 전이
  • ◾ 고아 객체
  • Refernece
  1. Spring
  2. Spring Data

프록시와 연관관계 맵핑

특정 엔티티를 조회할 때 그 엔티티에 연관된 엔티티들도 한번에 같이 조회하는 것이 아니라 실제 엔티티 객체 대신 DB 조회를 지연할 수 있는 가짜 객체를 프록시 객체라고 하고 이를 지연 로딩이라고 한다. 실제 연관된 엔티티가 있다면 JPA는 같이 조회하게 되는데 연관된 데이터의 정보가 필요가 없기도 하고 일대다의 맵핑이라면 한번의 조회가 아닌 1+N의 조회를 하기 때문에 성능상의 문제로 지연로딩을 수행해야 할 시점이 있다.

◾ 사용 방법

Member member = em.find(Memeber.class, "member1");  //원래 조회 방법
Member member = em.getRefernece(Member.class, "member1"); //지연 로딩(프록시 객체 생성)
member.getName();  //실제 데이터를 조회할때 DB조회

EntityManager.getRefernce()메서드를 사용하면 해당 엔티티의 프록시 객체가 생성 되고 getName()과 같이 엔티티의 데이터를 실제로 조회하는 시점에 영속성 컨텍스트에 엔티티의 유무를 파악하고 없다면 그때서야 조회를 수행한다.

◾ 특징

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

  • 영속성 컨텍스트에 찾는 엔티티가 존재할 시 DB조회가 아닌 실제 엔티티를 반환

  • 초기화는 영속성 컨텍스트의 도움이 필요하기 때문에 준영속상태의 프록시를 초기화 시 org.hibernate.LazyInitializationException예외를 발생

◾ isLoaded()

boolean isLoad = em.getEntityManagerFactory().getPersistenceUnitUtil().isLoaded(entity);

프록시 객체인 entity가 초기화가 되었는지 확인하는 메서드이다.

즉시로딩과 지연로딩

연관관계 설정시에 어노테이션(@ManyToOne ...)에 로딩전략을 설정할 수 있다.

@Enity
public class Member{
    //...
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "TEAM_ID")
    private Team team;
}

즉시 로딩은 FetchType.EAGER , 지연 로딩은 FetchType.LAZY로 설정이 가능하고 즉시로딩시에는 대부분의 JPA구현체는 성능을 위해 Join으로 쿼리를 날린다.

그런데 Member는 팀이 없을 수도 있는데 inner join을 하게 되면 조회가 되지 않는 Member,Team이 있을 수도 있기 때문에 기본전략으로 외부 조인을 수행하게 된다. 별도로 Inner join을 수행하도록 하고 싶다면 @JoinColumn(nullable = false)와 같이 nullable옵션을 false로 설정하면 JPA는 null이 없다는 것을 보고 inner조인을 사용한다.

JPA구현체 중 하나인 하이버네이트는 엔티티를 영속 상태로 만들때 엔티티에 컬렉션(List, Map...) 이 있다면 컬렉션을 추적,관리 목적으로 원본 컬렉션을 하이버네이트가 제공하는 내장 컬렉션으로 변경한다.(이를 컬렉션 래퍼라고 한다.) 그래서 1:N과 같이 컬렉션 필드가 있다면 프록시 객체가 지연 로딩을 수행하는 것이 아니라 컬렉션 래퍼가 지연 로딩을 처리해준다.

◾ 기본 전략

  • ManyToOne, OneToOne : 즉시 로딩

  • OneToMany, ManyToMany : 지연 로딩

컬렉션을 즉시 로딩하는 것은 비용이 많이 들기 때문에 지연로딩을 기본 전략으로 수행한다.

김영한 저자는 모든 연관관계는 지연 로딩을 사용하고 개발 완료단계에서 성능 측정후 필요한 곳에 즉시 로딩을 사용하는 방법으로 최적화하는 것을 추천하고 있다.

영속성 전이

연관관계 어노테이션의 cacade 옵션으로 영속성 전이를 JPA는 제공한다.

@Enity
public class Team{
    //...
    @OneToMany(mappedBy= "team", cascade = CascadeType.PERSIST)
    private List<Member>  members;
}

엔티티를 저장할때 연관된 모든 엔티티도 영속상태이어야 하기 때문에 특정 엔티티만 영속화 해도 연관된 엔티티도 같이 영속화하는 기능 이다.

저장뿐만이 아닌 삭제할때도 영속성 전이가 가능하고 제공하는 옵션은 다음과 같다.

public enum CascadeType{
    ALL,        //모두 적용
    PERSIST,    //영속
    MERGE,      //병합
    REMOVE,     //제거
    REFRESH,
    DETACH
}

영속성 전이도 쿼리와 같이 메서드호출이 아닌 flush를 호출할 때 전이가 발생한다.

◾ 고아 객체

JPA는 부모엔티티의 컬렉션에서 참조가 끊긴 자식 엔티티를 자동으로 삭제하는 기능을 제공한다.

@Enity
public class Parent{
    //...
    @OneToMany(mappedBy= "team", orphanRemoval = true)
    private List<Child>  Children;
}

//business logic
Parent parent = em.find(Parent.class, id);
parent.getChildren().remove(0);

마찬가지로 연관관계 어노테이션 옵션으로 설정이 가능하고 컬렉션에서 지우고 플러시를 하게 되면 자동으로 DELETE 쿼리가 실행된다. 또한, 부모를 제거하게 되면 모든 연관된 자식 객체들은 연관관계가 끊기기 때문에 모든 자식들도 지워지게 되고 이는 CascadeType.REMOVE와 동일한 기능이다.


Refernece

자바 ORM 표준 JPA 프로그래밍 책 (김영한 저)

PreviousJPA 최적화Next연관관계

Last updated 3 years ago