JPA 영속성 관리

minjun kim·2025년 6월 20일

JPA

목록 보기
3/4

JPA에서 중요한게
1, 객체와 관계형 DB 매핑하는것
2. 영속성 컨텍스트

영속성 컨텍스트

엔티티를 영구 저장하는 환경
EntityManager.persist(entity);

논리적인 개념, 엔티티 매니저를 통해 영속성 컨텍스트에 접근

엔티티의 생명주기

- 비영속

영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

- 영속

영속성 컨텍스트에 관리되는 상태

- 준영속

영속성 컨텍스트에 저장되었다가 분리된 상태

- 삭제

삭제된 상태

해당 영속성 컨텍스트의 이점에는
1차캐시
동일성 보장
트랜잭션을 지원하는 쓰기지연
변경감지 (dirty checking)
지연로딩 (Lazy Loding)

1차캐시

영속된 컨텍스트에 저장해 놨다가 조회할 수 있다.

만약에 1차캐시에없으면 1차캐쉬에 저장하고 DB에서 조회한다

영속 엔티티의 동일성

이런 1차캐쉬를 사용하면 영속 엔티티의 동일성을 보장

mybatice에서 생각해보면 리턴값으로 new해서 새로운 객체를 반환해줬다.
생각 해보면 장점은 DB를 두번조회하지않는것에서 불필요한 쿼리/객체 생성을 방지해준다.

Repeatable read를 하면서도 트랜잭션 내에서는 값이 항상 동일하게 유지된다.
읽을 때마다 값이 바뀌는 문제를 막아줌. -> 이걸 애플리케이션단에서 제공

그리고 동일성보장해주면 == 비교를 하더라도 같다고 표시하기 때문에 비즈니스 로직에서 버그를 줄여줌.

if (order.getMember() == em.find(Member.class, 1L)) {
    // true → 예상대로 동일한 인스턴스
}

엔티티 등록 트랜잭션을 지원하는 쓰기 지연

커밋하는 순간에 DB에 insert sql을 보낸다.

엔티티 수정 변경감지

생각해보니 엔티티를 수정할때 값을 변경후 update문을 써줘서 적용해주는 부분이 존재해야된다고 생각했다.

1차 캐쉬에 엔티티와 스냅샷을 비교해서 자동으로 update문을 생성하고 DB에 적용한다.

플러쉬

영속성 컨텍스트의 변경내용을 데이터베이스에 반영
단 커밋은 아니다.-> insert update delete sql을 보내는 것만 한다.

플러쉬 다음에 동작한다.

  1. 변경감지
  2. 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송

방법

  1. em.flush() - 직접 호출
  2. 트랜잭션 커밋 - 플러시 자동 호출
  3. JPQL 쿼리 실행 - 플러시 자동 호출

플러쉬가 자동으로 나가는 이유가
플러쉬 모드 옵션이 있다 .

em.setFlushMode(FlushModeType.COMMIT)
FlushModeType.AUTO
커밋이나 쿼리를 실행할 때 플러시 (기본값) 

FlushModeType.COMMIT
커밋할 때만 플러시

플러시 특징

1. 영속성 컨텍스트를 비우지 않음

flush()를 하면 DB에 SQL을 보낼 뿐이지,

현재 EntityManager가 관리 중인 영속 엔티티는 그대로 유지됨

em.flush();  // SQL은 나가지만, em 안의 객체들은 여전히 영속 상태

→ flush ≠ clear
→ clear는 영속성 컨텍스트를 비우는 명령 (em.clear())

2. 영속성 컨텍스트의 변경내용을 DB에 동기화

JPA는 엔티티를 변경해도 바로 DB에 UPDATE 쿼리 안 날림

대신 영속성 컨텍스트에만 반영

flush()를 호출하거나 commit 시점에 변경된 내용을 SQL로 변환해서 DB에 반영

Member m = em.find(Member.class, 1L);
m.setName("변경됨");   // 이 순간엔 SQL 안 날아감

em.flush();           // 이 시점에 UPDATE 쿼리 나감

3. 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨

보통은 굳이 flush()를 수동 호출하지 않아도 됨

왜냐면 JPA는 tx.commit() 시점에 자동으로 flush를 수행함

즉, 트랜잭션 내 변경 내용은 커밋 직전에 DB에 한 번에 반영됨

profile
배움의 흔적을 남기고 싶습니다.

0개의 댓글