본문 바로가기

카테고리 없음

영속성 컨텍스트 정리

# 영속성 컨텍스트 # 엔티티 매니저 # 엔티티의 4가지 상태 # flush

 

JPA에서 주요한 개념인 '영속성 컨텍스트' 는 다양한 기능을 제공합니다.

 

영속성 컨텍스트는 엔티티의 생명주기를 관리하는 공간으로,

캐시처럼, DB에서 조회한 데이터(엔티티)는 보관하여 같은 데이터를 더 빠르게 접근할 수 있게 해주고

버퍼처럼, 데이터(엔티티) 등록/수정/삭제 쿼리를 저장했다 한 번에 보냄으로써 성능을 향상시켜줍니다.

또한, 데이터(엔티티) 변경 사항을 감지하여 update 쿼리를 자동으로 만들어주기도 합니다.

 

이 기능은 '영속 상태'일 때만 동작합니다.

 

'엔티티 매니저'는 아래 그림처럼 여러 함수를 이용하여 엔티티의 생명주기를 관리합니다.

엔티티의 4가지 상태 (엔티티는 테이블에 대응하는 클래스입니다.)

1. 비영속(New): 영속성 컨텍스트와 전혀 관계가 없는 상태

2. 영속(Managed): 영속성 컨텍스트에 저장된 상태

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

4. 삭제(Removed): 삭제된 상태

 

엔티티 매니저는 persist() 함수를 이용하여 엔티티를 영속 상태로,

find() 함수를 이용하여 영속성 컨텍스트에 찾는 엔티티가 없다면 DB에서 조회해 영속 상태로 변화시킵니다.

merge() 함수는 find() 함수에서 더 나아가 DB에도 없다면 새로운 엔티티를 생성해 영속 상태로 변화시킵니다.

또한, close(), clear() 함수를 이용해 영속성 컨텍스트를 종료/초기화해주어 엔티티를 준영속 상태로 만들어줍니다.

remove() 함수를 이용해 영속성 컨텍스트에서 삭제하여 삭제 상태로 만들어줍니다.

 

'flush'란 영속성 컨텍스트에 모아놓은 등록/수정/삭제 쿼리를 DB에 반영하는 것을 의미합니다.

아래 상황일 때 플러시가 일어나 쿼리가 DB에 반영되게 됩니다.

1. 위 그림의 flush() 함수 사용

2. 트랜잭션 커밋 시

3. JPQL 쿼리 실행 시

 

JPQL을 실행하면 SQL로 변환되어 DB에서 엔티티를 조회합니다. 따라서 아래 코드에서 JPQL 실행 시 플러시하지 않으면, 원하는 결과를 얻을 수 없습니다. Item 목록을 조회하기 전에 item1, 2, 3을 저장하는 쿼리는 만들어졌지만 DB에 반영되지 않았기 때문입니다. 이러한 문제를 예방하기 위해 JPQL을 실행할 때 플러시를 자동 실행하게 됩니다.

// 등록 쿼리 영속성 컨텍스트에 저장(쿼리 실행 안함)
em.persist(item1);
em.persist(item2);
em.persist(item3);

// JPQL 실행
query = em.createQuery("select i from Item i", Item.class);
List<Item> item = query.getResultList();

 

이 플러시 모드는 엔티티 매니저에 직접 지정할 수 있습니다.

1. FlushModeType.AUTO: 커밋이나 쿼리 실행할 때 플러시(기본값)

2. FlushModeType.COMMIT: 커밋할 때만 플러시 -> 성능 최적화를 위해 사용