[JPA] 영속성 컨텍스트란? (엔티티 생명주기)

오늘은 이전 프로젝트 진행할 때 실시간 알림 구현중 OSIV 때문에 connection이 반환되지 않아 문제가 발생했던 적이 있었는데 해당 문제가 왜 발생했는지 알아보기 위해 2번의 포스팅(영속성 컨텍스트, 지연로딩과 OSIV)을 통해 알아보려고 한다.

 

우선 최종 목표인 OSIV에 대한 간단한 정의부터 살펴보자.

OSIV(Open-Session-In-View)란?

OSIV는 영속성 컨텍스트를 뷰까지 열어준다는 의미이다. 영속성 컨텍스트가 살아있으면 엔티티는 영속 상태로 유지된다. 따라서 뷰에서도 지연 로딩을 사용할 수 있다고 한다.

 

오늘은 지연로딩에 대해 공부하기 이전에 영속성 컨텍스트부터 알아보자.

 

영속성 컨텍스트란?

영속성 컨텍스트는 엔티티를 영구 저장하는 환경을 말한다. 간단히 말하면 엔티티를 저장하고 관리하는 저장소라고 생각하자.

 

영속성 컨텍스트는 어플리케이션이 데이터베이스에서 가져온 객체를 보관하는 역할을 하는데 엔티티 매니저 (EntityManager)를 통해서 영속성 컨텍스트에 접근한다. 엔티티 매니저는 connection이 필요한 시점에 엔티티 매니저 팩토리가 생성한다.

 

https://ttl-blog.tistory.com/108

엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하기 때문에 공유해서 사용해야 한다.
한 번만 생성하는 이유는 엔티티 매니저 팩토리를 생성하는 비용이 상당히 크기 때문이다.

그에 반해 엔티티 매니저는 생성하는 비용이 거의 들지 않기 때문에 필요에 따라 엔티티 매니저 팩토리가 엔티티 매니저를 생성해서 사용한다.

(엔티티 매니저가 생성되는 시점에 영속성 컨텍스트가 만들어진다.)

 

영속성 컨텍스트는 크게 2가지 영역으로 나뉜다.

 

https://siyoon210.tistory.com/138

1. 1차 캐시 저장소

1차 캐시 저장소는 엔티티의 생명 주기 중 영속 상태인 엔티티를 저장하는 곳이다. (엔티티의 생명 주기는 아래에서 알아보자)

일단 영속 상태의 엔티티는 아직 DB에 저장되기 전이다. 위의 그림만 보아도 DB와 1차 캐시 저장소 공간이 떨어져 있는 것을 볼 수 있다.

즉, 영속 상태의 엔티티를 영속성 컨텍스트가 저장하고 관리만 하고 있는 상태이다.

 

2. 쿼리문 저장소

쿼리문 저장소는 쿼리문(sql)을 보관해 두는 곳인데 DB에 접근하는 횟수를 최소화하기 위해서 쿼리문을 최대한 모았다가 한 번에 DB에 접근한다. 이 행위를 flush라고 한다.

 

다시 말해 flush를 통해 영속성 컨텍스트에서 보관하고 있는 엔티티를 DB에 반영하는 것이다.

 

엔티티의 생명 주기

위에서 말한 엔티티의 생명 주기에 대해 알아보자.

https://tall-developer.tistory.com/7

1. 비영속(new/transient)

비영속 상태는 엔티티 객체를 생성'만'한 상태로 영속성 컨텍스트, DB와는 전혀 관계가 없는 상태이다.

 

2. 영속(managed)

영속성 컨텍스트에 저장된 상태이고 엔티티가 영속성 컨텍스트에 의해 관리되는 상태이다.

영속성 컨텍스트에 의해 관리는 되고 있지만 DB에 저장된 상태는 아니다.

 

3. 준영속(detached)

영속성 컨텍스트가 관리하던 영속 상태의 엔티티를 더 이상 관리하지 않는 상태를 준영속 상태라고 한다. 즉 영속성 컨텍스트에 저장되었다가 분리된 상태이다.

 

4. 삭제(removed)

엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한 상태이다.

 

다음 포스팅에서는 위에서 언급한 지연로딩이 무엇인지, 그리고 영속성 컨텍스트를 배웠으니 OSIV에 대해 더 정확히 알아보자.