JPA

영속성 컨텍스트란?(영속성 관리에 대하여)

방구석 대학생 2020. 9. 8. 22:03

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

- JPA 를 이해하려면 영속성 컨텍스트(Persistence Context) 를 이해해야 한다.

JPA 에서는 아래의 두 가지가 가장 중요하다고 볼 수 있다.

1. 객체와 관계형 데이터베이스 간 매핑(Object Relational Mapping)

2. 영속성 컨텍스트(Persistence Context)

 

1 은 데이터의 정적인 매핑과정을 말하며, 2 는 실제 JPA 내부에서 동작하는 매커니즘을 말한다.

여기서 내부 동작 매커니즘인 영속성 컨텍스트를 명확하게 이해하면 JPA 가 내부적으로 어떻게 동작하는지 이해할 수 있다.

 

EntityManagerFactory 에서 EntityManager 클래스의 객체를 생성하면, 그 객체는 내부적으로 데이터베이스 커넥션을 이용해서 DB 를 사용하게 된다.

- 요청 -> EntityManagerFactory(생성) -> EntityManager(사용) -> conn(커넥션 풀) -> DB

 

보통 entity 를 데이터베이스에 저장할 때 EntityManager 클래스의 persist 메소드를 호출한 이후 트랜잭션 커밋을 통해 데이터베이스에 데이터 삽입 쿼리를 전달하여 entity 를 데이터베이스에 저장하게 된다.

즉, 여기서 EntityManager 클래스의 persist 메소드는 사실 DB 가 아니라 영속성 컨텍스트라는 곳에 저장하게끔 해주는 메소드인 것이다.

 

- 그렇다면 영속성 컨텍스트(Persistence Context)는 무엇일까?

영속성 컨텍스트는 entity 를 영구 저장하는 환경이라는 뜻으로 사실 EntityManager.persist(entity) 는 데이터베이스에 entity 를 저장하는 것이 아니라 영속성 컨텍스트를 이용해서 entity 를 영속화 한다는 뜻이다.

여기서 영속성 컨텍스트는 논리적인 개념이기 때문에 눈에 보이는 실체가 아니며, 위의 예문에서 보았듯 EntityManager 클래스의 메소드를 통해 영속성 컨텍스트에 접근할 수 있다.

 

보통 EntityManager 클래스의 객체를 생성하면 그 객체 안에 1 : 1 로 영속성 컨텍스트가 생성된다.

(EntityManager 안에 영속성 컨텍스트가 있는 눈에 보이지 않는 공간이 생긴다는뜻 - J2SE 환경의 경우에 해당한다.)

그러나 J2EE, 스프링 프레임워크 같은 컨테이녀 환경의 경우 EntityManager 와 영속성 컨텍스트(Persistence Context) 가 N : 1 의 관계가 될 수 있다.

EntityManager 내부에 존재하는 영속성 컨텍스트

 

- Entity 는 생명주기가 존재한다.

1. 비영속    2. 영속    3. 준영속    4. 삭제

 

1. 비영속 : 아래 코드와 같이 최초에 객체를 생성한(new) 상태. -> persist 메소드를 호출하기 이전, JPA 와 관계없이 객체만 생성한 상태이다.

// 비영속
Memeber member = new Member();
member.setId(101L);
member.setName("HelloJPA");

 

2. 영속 : persist 메소드를 호출할 경우의 상태. -> EntityManager 안에 있는 영속성 컨텍스트 안에 생성한 객체가 들어가게 되면서 영속 상태가 된다.(주의, 데이터베이스에 객체가 저장되는 것이 아니다.)

// 비영속
Memeber member = new Member();
member.setId(101L);
member.setName("HelloJPA");

em.persist(member); // 영속(객체를 저장한 상태)

- 영속 상태가 된다고 데이터베이스에 쿼리가 전달되는 것이 아니다.

그렇다면 언제 쿼리가 전달될까? : 트랜잭션을 커밋하는 시점에 영속성 컨텍스트에 있는 객체에 대한 쿼리가 전달되게 된다.

 

3. 준영속 : EntityManager.detach(object) 를 코드상에서 실행하면 persist 호출로 인해 영속성 컨텍스트 안에 들어가 있던 객체가 지워지게 된다.(즉, entity 를 영속성 컨텍스트에서 분리시킨다.)

// 비영속
Memeber member = new Member();
member.setId(101L);
member.setName("HelloJPA");

em.persist(member); // 영속(객체를 저장한 상태)
em.detach(member); // 준영속

 

4. 삭제 : EntityManager.remove(object) 를 통해 실제 데이터베이스 에서 객체를 삭제한다.

// 비영속
Memeber member = new Member();
member.setId(101L);
member.setName("HelloJPA");

em.persist(member); // 영속(객체를 저장한 상태)
em.remove(member); // 삭제

 

- 영속성 컨텍스트의 이점

애플리케이션과 데이터베이스 사이에 중간 계층으로서 영속성 컨텍스트가 존재하게 되는데

이로 인해 아래와 같은 몇가지 이점들을 얻을 수 있게 된다.

1. 1차 캐시로서의 영속성 컨텍스트 활용

2. 동일성 비교(identify) 보장(자바 컬렉션에서 == 비교와 같은 동일성 비교를 말한다.)

3. 트랜잭션을 지원하는 쓰기 지연, 즉 버퍼링(transactional write-behind)

4. 변경 감지(Dirty Checking)

5. 지연 로딩(Lazy Loading)

 

각 요소에 대한 이점은 다음 글에서 알아보자.