📖
Kyu9's Repo
  • Library of mameil
  • 이슈 경험
    • 20230220_트랜잭션
    • 20230306_캐싱이슈
    • 20230722_테스트코드에서 @Transactional
    • 20230807_deadlock
  • 인턴 스터디
    • Gradle
    • Stream, Optional, 람다식
    • JVM의 메모리 구조, Garbage Collector
    • RESTful API
    • Microservice Architecture
    • HTTP
    • 웹서버란 무엇인가
    • Git Branch
    • TDD
    • Redis을 이용한 캐시
    • Thymeleaf
    • 정리가 필요한 자료들
    • SpringBoot Management
    • 테스크 코드 분할
  • 동아리 스터디
    • 기본 SQL 공부
      • SQL의 기본 개념
      • SELECT 문장을 이용하여 원하는 데이터 출력하기
        • 집합 연산자 사용하기
        • where절에 비교 연산자를 사용해보기
        • SELECT_EX
        • 산술 연산자 사용해보기
      • 단일 행 함수 사용
        • lower/upper 함수 사용하기
        • length함수 사용하기
        • concat함수 사용
        • substr/mid/substring 함수 사용
        • instr함수 사용하기
        • lpad/rpad 함수 사용하기
        • trim/ltrim/rtrim 함수 사용하기
        • replace 함수 사용하기
        • round 함수 사용하기
        • truncate 함수 사용하기
        • mod함수 사용하기
        • ceil함수 사용하기
        • floor함수 사용하기
        • power 함수 사용하기
        • Date fn(날짜 함수)
        • 형 변환 함수
        • 일반함수란
    • a-ha 실습
    • 혼자서 만들어본 게시판
    • AWS 강의
  • 학교 나머지 공부 자료
    • 웹프레임워크(Spring)
      • Spring이란?
      • Webframework1-1
      • Webframework1-2
      • SpringBoot의 특징
      • SpringBoot 생성 방법
      • Spring Data JPA
      • SpringBoot Security
      • SpringBoot HATEOAS
  • 공부 자료들
  • WS 온라인 자바 스터디
    • Week1(JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.)
    • Week2(자바 데이터 타입, 변수 그리고 배열)
    • Week3(연산자)
    • Week4(제어문)
    • Week5(클래스)
    • Week6(상속)
    • Week7(패키지)
    • Week8(인터페이스)
    • Week9(예외처리)
    • Week10(멀티쓰레드 프로그래밍)
    • Week11(Enum)
    • Week12(Annotation)
    • Week13(I/O)
    • Week14(Generic)
    • Week15(람다식)
  • 백준문제
    • 입출력과 사칙연산
      • We love kriii(10718)
      • 고양이(10171)
      • 개(10172)
      • A+B(1000)
      • A-B(1001)
      • AxB(10998)
      • A/B(1008)
      • 사칙연산(10869)
      • 나머지(10430)
      • 곱셈(2588)
    • for문
      • 구구단(2739)
      • A+B - 3(10950)
      • 합(8393)
      • 빠른 A+B(15552)
      • N 찍기(2741)
      • 기찍 N(2742)
      • A+B - 7(11021)
      • A+B - 8(11022)
      • 별 찍기 - 1(2438)
      • 별 찍기 - 2(2439)
      • X보다 작은 수(10871)
    • if문
      • 두 수 비교하기(1330)
      • 시험 성적(9498)
      • 윤년(2753)
      • 사분면 고르기(14681)
      • 알람 시계(2884)
      • 오븐 시계(2525)
      • 주사위 세개(2480)
      • 영수증(25304)
    • While문
      • A+B - 5(10952)
      • A+B - 4(10951)
      • 더하기 사이클(1110)
    • 1차원 배열
      • 최소, 최대(10818)
      • 최댓값(2562)
      • 숫자의 개수(2577)
      • 나머지(3052)
      • 평균(1546)
      • OX퀴즈(8958)
      • 평균은 넘겠지(4344)
    • 함수
      • 정수N개의 합(15596)
      • 셀프 넘버(4673)
      • 한수(1065)
    • 문자열
      • 아스키코드(11654)
      • 숫자의 합(11720)
      • 알파벳 찾기(10809)
      • 문자열 반복(2675)
      • 단어 공부(1157)
      • 단어의 개수(1152)
      • 상수(2908)
      • 다이얼(5622)
      • 크로아티아 알파벳(2941)
      • 그룹 단어 체커(1316)
    • 기본수학-1
      • 손익분기점(1712)
      • 벌집(2292)
      • 분수찾기(1193)
      • 달팽이는 올라가고 싶다(2869)
      • ACM 호텔(10250)
      • 부녀회장이 될테야(2775)
      • 설탕 배달(2839)
      • 큰 수 A+B(10757)
      • Fly me to the Alpha Centauri(1011)
    • 기본수학-2
      • 소수 찾기(1978)
      • 소수(2581)
      • 소인수분해(11653)
      • 소수 구하기(1929)
      • 베르트와 공존(4948)
    • 재귀
      • 하노이 탑 이동 순서(11729)
      • 피보나치 수 5(10870)
      • 별 찍기(2447)
    • 브루트 포스
      • 블랙잭(2798)
      • 분해합(2231)
      • 덩치(7568)
      • 체스판 다시 칠하기(1018)
      • 영화감독 슘(1436)
    • 집합과 맵
      • 숫자 카드(10815)
      • 문자열 집합(14425)
      • 숫자 카드2(10816)
      • 듣보잡(1764)
      • 대칭 차집합(1269)
      • 서로 다른 부분 문자열 갯수(11478)
    • 정렬
      • 수 정렬하기(2750)
      • 수 정렬하기 2(2751)
      • 수 정렬하기 3(10989)
      • 통계학(2108)
      • 소트인사이드(1427)
      • 좌표 정렬하기(11650)
      • 좌표 정렬하기2(11651)
      • 단어 정렬(1181)
      • 나이순 정렬(10814)
      • 커트라인(25305)
      • 좌표압축(18870)
    • 백트래킹
      • N과 M - 1(15649)
      • N과 M - 2(15650)
      • N과 M - 3(15651)
      • N과 M - 4(15652)
      • N-Queen(9663)
      • 스도쿠(2580)
      • 연산자 끼워넣기(14888)
      • 스타트와 링크(14889)
    • 이분 탐색
      • 수 찾기(1920)
    • 동적계획법
      • 피보나치 함수(1003)
      • 신나는 함수 실행(9184)
      • 01타일(1904)
      • 파도반 수열(9461)
      • RGB거리(1149)
      • 정수 삼각형(1932)
      • 계단 오르기(2579)
      • 1로 만들기(1463)
      • 쉬운 계단 수(10844)
      • 포도주 시식(2156)
      • 가장 긴 증가하는 부분 수열(11053)
      • 가장 긴 바이토닉 부분 수열(11504)
      • 전깃줄(2565)
      • LCS(9251)
      • 연속합(1912)
      • 평범한 배낭(12865)
      • 더하기(9095)
    • DFS와 BFS
      • 미로탐색(2178)
      • 바이러스(2606)
      • DFS와 BFS(1260)
      • 단지번호붙이기(2667)
      • 전쟁 - 전투(1303)
      • 숨바꼭질(1697)
      • 데스 나이트(16948)
      • 나이트의 이동(7562)
      • 녹색 옷 입은 애가 젤다지?(4485)
      • 음식물 피하기(1743)
      • A->B (16953)
      • 숨바꼭질 3(13549)
      • 숨바꼭질 2(12851)
    • 구현
      • 치즈(2636)
  • 프로그래머스 문제
    • SQL
      • Animal Table - Oracle
      • Animal Table - MySQL
      • Animal Table2 - Oracle
      • Animal Table 3,4 - Oracle
    • Lv1
      • 두 개 뽑아서 더하기
      • 제일 작은 수 제거하기
      • 문자열 내 p와 y의 개수
      • 예산
      • 자릿수 더하기
      • 두 정수 사이의 합
      • 같은 숫자는 싫어
      • 가운데 글자 가져오기
      • 수박수박수박수박수박수?
      • 나누어 떨어지는 숫자 배열
      • 2016년
      • 폰캣몬
      • 서울에서 김서방 찾기
      • 문자열을 정수로 바꾸기
      • 소수 만들기
      • 문자열 다루기 기본
      • 소수 찾기(에라토스테네스의 체)
      • 숫자 문자열과 영단어
      • 이상한 문자 만들기
      • 없는 숫자 더하기
      • 문자열 내림차순으로 배치하기
      • 문자열 내 마음대로 정렬하기
      • 약수의 개수와 덧셈
      • 콜라츠 추측
      • 자연수 뒤집어 배열로 만들기
      • 신규 아이디 추천
      • 비밀지도
      • 크레인 인형뽑기 게임
      • 실패율
      • 로또의 최고 순위와 최저 순위
      • 키패드 누르기
      • 정수 내림차순으로 배치하기
    • Lv2
      • 행렬의 곱셈
      • 영어 끝말잇기
      • 영어 끝말잇기
      • N개의 최소 공배수
      • 피보나치 수
      • 124 나라의 숫자
      • 짝지어 제거하기
      • 프린터
      • 다음 큰 숫자
      • 최댓값과 최솟값
      • 최소값 만들기
      • 숫자의 표현
      • JadenCase 문자열 만들기
      • 오픈채팅방
      • 영어 끝말잇기
      • 멀쩡한 사각형
      • 올바른 괄호
      • 위장
      • 기능개발
      • 더 맵게
      • 스킬트리
    • 완전탐색
      • 모의고사(Lv1)
      • 카펫(Lv2)
      • 소수 찾기(Lv2)
    • 정렬(Sorting)
      • K번째 수(Lv1)
      • 가장 큰 수(Lv2)
      • H-Index(Lv2)
    • 해시(Hash)
      • 완주하지 못한 선수(Lv1)
      • 전화번호 목록(Lv2)
    • 탐욕법(Greedy)
      • 체육복(Lv1)
      • 큰 수 만들기(Lv2)
      • 구명보트(Lv2)
    • 동적계획법(DP)
      • 정수 삼각형(Lv3)
    • 깊이/너비 우선 탐색(DFS/BFS)
      • 타겟 넘버(Lv2)
      • 네트워크(Lv3)
      • 단어 변환(Lv3)
  • 스프링부트 책
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
  • JPA 책
    • 프로젝트 세팅 및 기본설정
    • 영속성 관리 개념
    • 엔티티 매핑
      • 실습 예제
    • 연관관계 매핑 기초
      • 실습 예제
    • 다양한 연관관계 매핑
      • 다대일, 일대다 관계
      • 일대일, 다대다 관계
      • 실습 예제
    • 고급 매핑
      • 상속 관계 매핑
      • @MappedSuperclass
      • 복합 키와 식별 관계 매핑
      • 조인 테이블
    • 프록시와 연관관계 관리
      • 프록시
      • 즉시 로딩과 지연 로딩
      • 영속성 전이, 고아 객체
    • 값 타입
      • 임베디드 타입
      • 값 타입과 불변 객체
      • 값 타입의 비교, 컬렉션
    • 객체지향 쿼리 언어
      • JPQL part1
      • JPQL part2
      • JPQL part3
      • QueryDSL
      • NativeSQL
      • 객체지향 쿼리 심화
    • 응용 애플리케이션
      • 엔티티 설정
    • 스프링 데이터 JPA
      • 공통 인터페이스
  • Kotlin In Action
    • 코틀린의 특징
    • 코틀린의 기초
    • 함수 정의와 호출
    • 클래스, 객체, 인터페이스
    • 람다 방식
    • 코틀린 타입 시스템
    • 연산자 오버로딩과 기타 관례
    • 고차함수
    • 제네릭스
    • 애노테이션과 리플렉션
    • 코루틴
  • Oracle
    • Oracle 기본
    • Oracle 심화
  • SQL_연습
    • Revising the Select Query
    • Basic Select
    • Advanced Select
    • Basic Select 2
  • SQL 첫걸음(책)
    • Day 1
    • Day 2
    • Day 3
    • Day 4
    • Day 5
    • Day 6
    • Day 7
    • Day 8
    • Day 9
    • Day 10
    • Day 11
    • Day 12
    • Day 13
    • Day 14
    • Day 15
    • Day 16
    • Day 17
    • Day 18
    • Day 19
    • Day 20
    • Day 21
    • Day 22
    • Day 23
    • Day 24
    • Day 25
    • Day 26
    • Day 27
    • Day 28
    • Day 29
    • Day 30
  • 더 자바 코드를 조작하는 다양한 방법
    • JVM 이해하기
    • 바이트코드 조작
    • 리플렉션
    • 다이나믹 프록시
    • 애노테이션 프로세서
  • 더 자바, 애플리케이션을 테스트하는 다양한 방법
    • JUnit5
    • Mockito
    • 도커와 테스트
    • 성능, 운영이슈, 아키텍처 테스트
  • 이펙티브 자바
    • item1 - 생성자 대신 정적 팩토리 메소드를 고려하라
    • item2 - 생성자에 매개변수가 많다면 빌더를 고려하라
    • item3 - 생성자나 열거타입으로 싱글턴임을 보증하라
    • item4 - 인스턴스화를 막기 위해선 private 생성자를 사용하라
    • item5 - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
    • item6 - 불필요한 객체 생성을 피하라
    • item7 - 다 쓴 객체 참조를 해제하라
    • item8 - finalizer와 cleaner 사용을 피하라
    • item9 - try-finally 보다 try-with-resources을 사용하라
    • item10 - equals는 일반 규약을 지켜 재정의하라
    • item11 - equals을 재정의하려면 hashCode도 재정의하라
    • item12 - toString을 항상 재정의하라
    • item13 - clone 재정의는 주의해서 진행하라
    • item14 - Comparable을 구현할지 고민하라
  • Elastic Search
    • 강의 Summary
    • Elastic Summary 개념 정리
    • Elastic Summary 적용 정리
  • 토비의 스프링 강의
    • 스프링부트 살펴보기
    • 독립 실행형 서블릿 애플리케이션
  • k8s
    • minikube 설치
    • jenkins 추가
  • Article
    • Choosing the Right MessageBroker
Powered by GitBook
On this page
  • 엔티티 매니저, 엔티티 매니저 팩토리?
  • 영속성 컨텍스트?
  • 엔티티의 생명 주기?
  • 영속성 컨텍스트의 특징
  • 엔티티 조회
  • 엔티티 등록
  • 엔티티 수정
  • 엔티티 삭제
  • 플러시
  • 준영속

Was this helpful?

  1. JPA 책

영속성 관리 개념

엔티티 매니저, 엔티티 매니저 팩토리?

Entity Manager - 엔티티를 C,R,U,D 등 관련된 것을 모두 관리한다. 즉 엔티티를 관리하는 관리자

EntityManager Factory? - 번역하면 엔티티 매니저를 만드는 공장이다.

여기서 팩토리는 팩토리 메서드 패턴이다. 팩토리 메소드 패턴은 부모 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이다. 엔티티 매니저 팩토리를 만드는 비용은 상당히 많이 든다. 그래서 하나만 만들어서 전체의 애플리케이션에서 공유하는 방향으로 사용한다.

엔티티 매니저 팩토리는 여러 스레드가 동시에 엔티티 매니저 팩토리에 접근해도 괜찮다 = 여러 스레드가 공유할 수 있다.

하지만 엔티티 매니저는 여러 스레드가 동시에 접근할 시 동시성 문제가 생겨서 공유하면 안됨

영속성 컨텍스트?

엔티티를 영구 저장하는 환경이라는 의미를 가지고 있으며 위에서 언급한 엔티티 매니저가 엔티티에 접근할 때 영속성 컨텍스트에서 관리한다. 영속성 컨텍스트는 논리적인 개념이라서 보이지는 않지만 대충 엔티티 매니저를 생성할 때 하나가 만들어진다고 보면 된다.

영속성 컨텍스트는 하나의 엔티티 매니저에 하나의 영속성 컨텍스트가 만들어진다고 생각하자

엔티티의 생명 주기?

4가지의 상태가 존재한다.

  • 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태

    • 단순하게 객체를 만들었을 때이기 때문에 DB에는 저장하지 않았으며 따라서 영속성 컨텍스트와도 관련이 없다

    • @Transient라는 애노테이션도 있다! → 이걸 사용하면 엔티티를 저장하는 과정에서 원하는 컬럼은 저장하지 않고 객체에서만 사용할 수 있다.

  • 영속(managed) : 영속성 컨텍스트에 의해 관리되고 있는 상태

    • 객체를 엔티티 매니저를 통해서 영속성 컨텍스트에 저장한 상태를 의미한다.

    • entitymanager.persist(엔티티)을 통해서 영속 시키고 entitymanager.find()나 JPQL을 사용해서 영속성 컨텍스트가 관리하고 있는 엔티티에 접근할 수 있다.

  • 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태

    • 영속성 컨텍스트가 엔티티를 더 이상 관리하지 않는다면 그것이 바로 준 영속 상태이다.

    • entitymanager.detach(엔티티)을 통해서 준영속 상태로 바꿔줄 수 있다. = 더 이상 관리하지 않을 수 있음

    • 이외에도 entitymanager.close()을 통해서 영속성 컨텍스트를 종료하거나 entitymanager.clear()을 통해서 영속성 컨텍스트를 초기화하면 해당 영속성 컨텍스트에서 관리하고 있던 모든 엔티티들은 준영속 상태로 변경된다.

  • 삭제(removed) : 삭제된 상태

    • 그냥 엔티티를 영속성 컨텍스트에서, 데이터 베이스에서 삭제하는 역할

    • entitymanager.remove()을 통해서 삭제

영속성 컨텍스트의 특징

  • 식별자

    • 영속성 컨텍스트에 엔티티를 영속시킬 때, 영속성 컨텍스트는 엔티티를 식별자 값으로 구분하게 된다. 이 식별자 값은 @Id 애노테이션을 통해서 구분하게 된다.

    • 따라서 영속 상태는 식별자 값이 반드시 있어야 한다. 만약 식별자 값이 없다면 예외 발생

  • 영속성 컨텍스트와 데이터베이스에 저장 시점

    • JPA는 트랜잭션을 커밋하는 순간에 영속성 컨텍스트에 새롭게 들어온 엔티티를 데이터 베이스에 반영하게 되고 이 현상을 flush라고 한다.

  • 관리의 장점

    • 1차 캐시, 동일성 보장, 트랜잭션을 지원하는 쓰기 지연, 변경 감지, 지연 로딩와 같은 기능을 지원

엔티티 조회

엔티티 컨텍스트의 내부에는 캐시 시스템이 존재하고 그것을 1차 캐시라고 한다. 그리고 엔티티 매니저에 저장되는 모든 엔티티는 1차 캐시에 저장되게 된다. 구성 자체는 맵이라고 생각하면 된다. 식별자-엔티티 이런 식으로 저장되었다고 생각하면 된다.

persist 함수를 사용하게 되면 맵 방식으로 1차 캐시에 저장하고 아직은 데이터베이스에 저장되지 않은 상황이다.

find 함수를 사용하게 되면 맵 방식으로 1차 캐시에서 우선적으로 식별자 값으로 엔티티를 찾고 1차 캐시에서 찾지 못했다면 데이터베이스에서 찾는다.

만약 1차 캐시에서 엔티티를 찾지 못해서 데이터베이스에서 조회하게 되었다면 영속성 컨텍스트 입장에서는 데이터 베이스에서 조회한 엔티티를 1차 캐시에 생성하고 나서 엔티티를 뱉어준다.

1차 캐시에서 저장하는 엔티티 인스턴스와 데이터 베이스에서 저장하는 엔티티 인스턴스는 동일하다. 그 의미는 객체가 같은 뿐만 아니라 그 객체가 가리키는 값까지 같다는 의미이고 완전히 같은 값을 의미한다.

자바 객체 동일성, 동등성 → 객체의 equals 함수를 사용해서 객체의 해쉬값 까지 비교하는 방식이다.

엔티티 등록

엔티티 매니저는 트랜잭션을 커밋하기 전까지는 내부 쿼리 저장소에 쿼리들을 모아둔다. 그리고 커밋할 때 저장해둔 내부 쿼리 저장소에 있는 쿼리들을 한꺼번에 보낸다. 이렇게 한꺼번에 내부 쿼리 저장소에서 모아둔 쿼리들을 트랜잭션 커밋 시 보내는 것을 쓰기 지연 이라고 한다.

위처럼 계속해서 persist을 통해서 엔티티를 저장할 때 쿼리문도 저장해뒀다가

commit()이 왔을 때 한꺼번에 flush()을 통해서 보내준다.

엔티티 수정

JPA로 엔티티를 수정할 때는 단순하게 엔티티를 조회해서 데이터만 변경하면 된다. 따로 update를 치지 않아도 그냥 영속성 컨텍스트에 가져와진 객체를 수정하는 것만으로도 알아서 데이터베이스에 수정이 된다. 그리고 이러한 기능을 변경 감지라고 한다.

흐름을 보면

스냅샷? - JPA는 엔티티를 영속성 컨텍스트에 저장할 떄 가장 최초 상태를 복사하는데 이 복사된 것을 스냅샷이라고 함

  1. flush()함수로 업데이트가 들어오면

  2. 엔티티와 스냅샷을 비교해서 변경된걸 찾고

  3. 수정 쿼리를 만들어서 쓰기 지연 저장소에 저장

  4. 쓰기 지연 저장소에 있는 쿼리를 데이터 베이스에 보냄

  5. 트랜잭션을 커밋

변경 감지의 특징은 아무런 엔티티나 모두 다 되는 게 아니라 오직 엔티티 매니저가 관리하고 있는 상태인 영속상태인 엔티티에만 적용이 가능하다!

변경 감지를 통해서 생성된 수정 SQL은 엔티티의 수정되는 부분만 수정하는 것이 아니라 엔티티의 모든 필드를 업데이트 친다 → 왜일까?

이유는 2가지

  • 모든 필드를 사용하면 수정 쿼리가 항상 같기 때문에 애플리케이션 로딩 시점에 수정 쿼리를 미리 생성해두고 재사용이 가능하다.

  • 데이터 베이스에 동일한 쿼리를 보내면 데이터베이스는 이전에 한 번 파싱된 쿼리를 재사용할 수 있다.

엔티티 삭제

엔티티를 삭제하기 위해서는 일단 조회를 통해서 확인을 하게 되고 remove()을 통해서 삭제를 하게 되는데 remove() 호출 → 삭제 쿼리를 지연 쓰기 저장소에 저장, 1차 캐시에서는 엔티티 삭제 → 커밋 시, flush 호출 → 데이터 베이스에 삭제 쿼리 전달

-그럴일은 없겠지만 remove를 통해서 삭제한 엔티티는 다시 재사용하지말자?

플러시

flush()는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영해주는 역할을 수행한다.

이것의 의미는 영속성 컨텍스트에 있는 변경 내용을 지우고 데이터베이스에 반영한다는 의미가 아니다!!! → 변경 사항이 있는 영속성 컨텍스트와 데이터베이스를 동기화 시키는 의미

동작순서

  1. 변경 감지를 통해서 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾고, 수정된 엔티티에 대한 수정 쿼리를 만들어서 쓰기 지연 저장소에 저장

  2. 쓰기 지연 저장소에서 SQL문을 데이터베이스에 전송

flush하는 방법

  1. 직접 entitymanager.flush()을 호출

    • 테스트하는 과정이나 특별한 겨우가 아니면 사용하지 않는다.

  2. 트랜잭션 커밋 시 flush()를 자동으로 호출

    • 데이터 베이스의 수정 사항을 SQL을 통해서 전달하지 않고 그냥 트랜잭션만 커밋하면 데이터 베이스에 수정 사항이 적용되지 않는다. 그래서 트랜잭션을 커밋하기 전, flush()을 호출해서 데이터 베이스에 적용시켜 하는데, JPA에서는 이런 사항을 미리 처리해주기 위해서 자동으로 트랜잭션을 커밋하기 전에 flush()을 호출하게 되어 있다.

  3. JPQL 쿼리 실행 시 flush()를 자동으로 호출

flush 옵션

flush를 하는데 옵션을 수동으로 지정할 수 있는데, javax.persistence.FlushModeType을 사용해서 지정해준다.

entitymanager.setFlushMode(타입)

  • FlushModeType.COMMIT : 커밋할 때만 flush → 최적화된 성능을 제공하기 위해서 사용

준영속

준영속 상태 이라는 의미는 영속되어 있었던 엔티티가 영속성 컨텍스트에서 분리(detached)되어 더 이상 영속성 컨텍스트의 기능을 사용하지 못하는 상태를 의미

여기서 영속성 컨텍스트의 기능이란 쓰기 지연 저장소나 1차 캐시에서 더 이상 준영속 엔티티를 저장하고 있지 않겠다는 의미

준영속 상태로 만드는 방법

  1. entitymanager.detach(엔티티) : 파라미터로 넣어준 엔티티만 준영속 상태로 바꿈

  2. entitymanager.clear() : 영속성 컨텍스트를 완전하게 초기화

  3. entitymanager.close() : 영속성 컨텍스트를 종료

clear() 와 close()의 차이를 생각해보면 비슷하다고 생각했지만 조금은 다르다

clear()를 통해서 여러가지로 쌓여있었던 엔티티들을 한 번 정리하고 사용하는 것이 가능

close()은 사용하던 영속성 컨텍스트를 한 번 지운다는 것

그래서 준영속 상태가 되면 어떻다는거지?

  1. 거의 비영속 상태에 가깝다

    • 일단은 중요한 영속성 컨텍스트를 사용할 수 없기 때문에 필요한 기능들을 사용할 수 없다

  2. 식별자 값을 가지고 있다

    • 준영속이기 때문에 한번 영속되었던 적이 있기 때문에 영속 상태였을 때 가지고 있었던 식별자 값을 그대로 가지고 있다

  3. 지연 로딩을 할 수 없다

    • (fetchType?에서 있는 lazy타입인데, 이후에 한 번 더 나오면 정리하자)

    • 지연 로딩은 실제 객체 대신 프록시 객체를 로딩하고 해당 객체를 실제 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방식인데, 애초에 프록시 객체를 가져오는 것부터 틀렸기 떄문에 불가능하다

그럼 준영속 상태에서 다시 영속상태로 변경하는 방법은?

병합(merge)

entitymanager.merge(엔티티) 이렇게 사용하고 사용하면 기존의 준영속 상태의 엔티티의 정보를 가지고 다시 새로운 영속 상태의 엔티티를 반환해준다.

다시 병합할때 위에서 언급했던 식별자 값을 아직도 가지고 있는게 사용되게 되는데,

실행순서를보자

  1. merge(엔티티) 실행

  2. 준영속 엔티티의 기존의 식별자 값을 가지고 1차 캐시를 뒤진다

  3. 1차 캐시에서 찾지 못했다면 데이터 베이스에서 찾는다

  4. 찾은게 있다면 그 엔티티에 엔티티 값을 채워 넣는다.

  5. 없다면 새로운 엔티티를 만들어서 병합

자 그럼 결국 값으로 넘어온 엔티티를 1차 캐시와 데이터베이스에서 찾아보고 없으면 새로운 엔티티를 만들어서 생성 있으면 있던 값에 채워넣는다.

이렇게 보니까 merge할 때는 준영속이나 비영속이나 상관없다는 것!

있는 값이라면 update 쿼리를 실행하고 없는 값이라면 save 쿼리를 실행하는구나

Previous프로젝트 세팅 및 기본설정Next엔티티 매핑

Last updated 3 years ago

Was this helpful?

: 커밋이나 쿼리를 실행할 때 flush해줌 → default

FlushModeType.AUTO
엔티티 등록 FLOW
엔티티 수정 FLOW