인프런에서 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 참고하여 작성한 글입니다.
영속성 컨텍스트란?
JPA는 데이터와 연관된 객체들을 Entity로 분류하여 관리합니다.
따라서 데이터를 읽거나, 조회하거나 쓰는 내용들이 Entity를 통해서 이루어지게 됩니다.
이러한 엔티티들을 JPA는 어떠한 곳에 저장하는데, 이 영역을 영속성 컨텍스트라고 합니다.
영속성 컨텍스트는 엔티티 매니저를 통해서 접근할 수 있는데, 이는 눈에 보이지 않는 논리적인 개념입니다.
엔티티 매니저란?
웹 어플리케이션은 어떤 요청이 들어오게 되면, 엔티티 매니저 팩토리에서 엔티티 매니저를 생성하여 할당해줍니다.
따라서 각 요청에 따라 해당 요청을 담당해주는 엔티티 매니저가 있게 됩니다.
이 엔티티 매니저는 DB에 접근하기 위한 커넥션 풀에서 커넥션을 꺼내 DB에 데이터를 넣거나 조회하는 작업 등을 수행할 수 있게 됩니다.
따라서 엔티티 매니저는 persist, findBy와 같은 메소드를 가지고 이 영속성 컨텍스트에서 엔티티들을 꺼내오거나 넣게 됩니다.
환경에 따라서 엔티티 매니저와 영속성 컨텍스트의 관계가 달라지게 되는데, 스프링 프레임워크같은 컨테이너 관리 중심의 환경에서는 엔티티 매니저 여러개가 하나의 영속성 컨텍스트를 바라보는 방식으로 되어있습니다.
엔티티의 생명주기
엔티티는 다음과 같은 생명주기를 가지고 있습니다.
각 상태들에 대해서 자세히 알아보겠습니다.
- New (비영속 상태)
제일 처음에 엔티티를 생성하면 가지게 되는 상태로, 영속성 컨텍스트와 어떤 관계로 맺혀져 있지 않은 초기 상태입니다.
EntityA e = new EntityA();
위와 같이 java에서 객체를 생성만 하고, 엔티티 매니저가 어떤 작업도 수행하지 않은 상태입니다.
이는 생성된 객체의 내부 변수를 바꾸는 등의 작업도 마찬가지로 엔티티 매니저가 알 수 없으니 영속성 컨텍스트에 영향을 미치지 않습니다.
- Managed (영속 상태)
엔티티 매니저를 통해서 무언가 작업이 수행되어 영속성 컨텍스트가 관리해주는 상태입니다.
즉, 영속성 컨텍스트 안에 영속 상태인 엔티티 객체가 들어가있는 모습입니다.
EntityA e = new EntityA();
...
엔티티 매니저 생성 및 트랜잭션 시작
...
entitymanager.persist(e);
다만 영속성 컨텍스트 안에 엔티티가 들어가있다고 해서 DB에 이들이 반영되는 것은 아닙니다.
트랜잭션을 시작했지만 아직 커밋된 상태가 아니기 때문입니다.
- Detach (준영속 상태)
엔티티 객체가 영속성 컨텍스트에서 분리된 상태입니다.
이는 단순히 영속성 컨텍스트에서 해당 객체가 지워진 것이기 때문에 영속 상태 이전으로 돌아간 모습으로 볼 수 있습니다.
entitymanager.detach(e);
- Remove (삭제)
엔티티 객체가 실제로 DB에서 삭제되는 상태이며, 영속성 컨텍스트에서도 삭제됩니다.
entitymanager.detach(e);
영속성 컨텍스트의 장점
그러면 왜 JPA는 DB에 바로 작업을 반영하지 않고 영속성 컨텍스트라는 중간다리를 하나 더 두는 걸까요?
- 동일성 보장
영속성 컨텍스트는 객체의 동일성을 보장해 줄 수 있습니다.
만약 DB에서 직접 엔티티를 넣고 꺼내게 된다면 내가 insert한 객체와 방금 전에 insert한 것을 꺼내온 객체가 같다는 것을 보장할 수 없습니다.
어플리케이션과 DB가 분리되어있으므로 내가 방금 넣은것과 가져온 것은 엄연히 다른 객체이기 때문이죠.
하지만 중간 단계에 영속성 컨텍스트를 둠으로써 이 객체를 영속성 컨텍스트가 관리해주니 동일성을 보장할 수 있게 됩니다.
- 1차 캐시의 역할
어플리케이션과 DB 사이의 중간 역할을 영속성 컨텍스트가 해줌으로써 캐싱이나 버퍼링과 같은 효율성 측면에서의 이득을 취할 수 있습니다.
- 트랜잭션 지원의 쓰기 지연
100개의 작업이 있다고 가정 할 때에 DB와 연결해서 100개의 작업을 그때그때 하는것보다는
이 작업들을 모아서 한번에 DB의 SQL로 쏘는 방법이 시간적인 면에서 더 효율적입니다.
- 변경 감지
만약 엔티티와 관련하여 update가 일어나면 JPA가 이를 자동으로 인식하게 됩니다.
- 지연 로딩
엔티티를 한번에 바로 가져오지 않고 필요한 시점에 가져오도록 함으로써 부하를 어느정도 줄일 수 있습니다.
이번 글에서는 영속성 컨텍스트에 대한 기본적인 내용과 엔티티 생명주기, 이점에 대해서 다뤄보았습니다.
다음 글에서는 영속성 컨텍스트가 엔티티를 관리하는 방법에 대해서 좀 더 상세히 배워보겠습니다.
'Spring > JPA' 카테고리의 다른 글
[JPA] 영속성 컨텍스트(2) - 영속성 컨텍스트의 엔티티 관리 (0) | 2021.09.22 |
---|