영속성 컨텍스트란?(영속성 관리에 대하여)
"인프런 - 자바 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 의 관계가 될 수 있다.
- 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)
각 요소에 대한 이점은 다음 글에서 알아보자.