JPA/JPA 기본

6. 영속성 컨텍스트

sdafdq 2023. 10. 20. 07:59

JPA에서 가장 중요한 2가지

객체와 RDB 매핑

영속성 컨텍스트

 

 

 

앞서, EntityManagerFactory와 EntityManager

EntityManagerFactory에서 앞서 우리가 명시한 persistence,xml대로 EntityManagerFactory가 만들어 지고,

거기서 이름을 지정하여 EntityManager를 생성할 수 있다.

그럼 이 EntityManager는 내부적으로 커넥션을 사용하여 DB와 소통한다.

 

 

 

 

 

 

 

영속성 컨텍스트란

엔티티를 영구 저장하는 환경.

 

우리가 

EntityManager.persist(entity);

하면 entity를 DB에 저장한다, 이렇게 배웠는데,

더 정확하게 말하면,

영속성 컨텍스트를 통해서 저 엔티티를 영속화 한다는 뜻이다.

즉, 저 순간 DB에 쿼리를 날려 저장시키는 게 아니다.

 

따지고 보면 DB가 아니라 영속성 컨텍스트 라는 곳에 저장한다는 뜻.

 

근데 이 영속성 컨텍스트라는 개념은 논리적인 것 이며, 눈에 보이지 않는다.

 

 

EntityManager 하나를 생성하면 그 안에 영속성 컨텍스트라는 공간이 하나 생기는 것이다.

EntityManager란 영속성 컨텍스트에 어떻게 Entity를 관리할 지 결정하는 객체이다.

 

EntityManager가 관리하는 Entity는 생명주기가 있다.

비영속(New) : 예를 들면 새로 생성한 Member, 영속성 컨텍스트와 전혀 관계가 없는.

 

영속(Managed) : EntityManager.persist(member) 하면 저 member라는 Entity는 영속성 컨텍스트에 관리되는 Entity가 된다.

 

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

삭제(Remove) : 삭제된 상태

 

Entity의 생명 주기

 

즉, 자바에서는 persist 하면 영속성 컨텍스트에서 관리하기 시작하는 대상이 되는 거고,

find()해서 DB에서 가져오면 또 관리하는 대상이 되는거다.

 

 

비영속

Member member= new Member();
member.serId("member1");
member.setUsername("회원1");

전혀 EntityManager와 관계가 없는

 

 

영속

Member member= new Member();
member.serId("member1");
member.setUsername("회원1");

// System.out.println("영속화 전");
em.persist(member);
// System.out.println("영속화 후");

member를 persist(영속화) 한다. 즉, member를 영속성 컨텍스트에서 관리하겠다는 뜻임.

persist 한다고 바로 쿼리가 날라가는 게 아니다.

 

 

준영속

em.detach(member);

영속성 컨텍스트에서 분리된 상태.

merge()시에 다시 영속성 컨텍스트에 넣을 수 있음.

 

 

삭제

em.remove(member);

말 그대로 DB에서 지운다고 하는 상태이다.

 

 

 

이런 상태들로 있다가, commit 시점에 쿼리를 날려 DB에 반영한다.

이러면 이점이

 

캐시: 바로바로 쿼리를 날리는 게 아니라 영속성 컨텍스트에 Entity의 상태라던지 저장해 둘 수 있으니까, 잠깐 캐싱할 수 있음.

 

동일성 보장 : 한 트랜잭션 안에서는 같은 DB, 즉 같은 Entity를 DB에서 두번 가져오면 캐시해놨다가 똑같은 거 주면 레퍼런스도 같음

 

트랜잭션을 지원하는 쓰기 지연 : commit 시점에 commit 전에 한번에 정리해서 쿼리를 날리기 때문에, 원하는 것들, 날리고 싶은 쿼리들을 모아뒀다가 한번에 날릴 수 있음.

 

변경감지 : 영속성 컨텍스트에 관리하면서 첫 상태를 캡쳐해 놓을 수도 있고, 그래서 뭔가 변화가 있다면 비교해서 감지 가능.

 

지연 로딩 : 예를 들면 딱 그 객체가 호출 되었을 때, 막 DB와 소통하면서 DB에서 여러 정보들을 가져와 객체와 묶는 코드 단계에서가 아니라, 예를 들어 isFirst라는 boolean을 저장해 놨다가 어떤 처음 가져올 때 프록시로 가져오는? 검사하는? 그런 게 가능. 그래서 isFirst가 참이면 그제서야 쿼리를 날려 DB에서 가져오고 isFirst상태를 false로 바꿈

 

 

 

'JPA > JPA 기본' 카테고리의 다른 글

8. 플러시  (0) 2023.10.20
7. 영속성 컨텍스트 2  (0) 2023.10.20
5. 개발  (0) 2023.10.19
4. 프로젝트 생성  (0) 2023.10.19
3. JPA  (0) 2023.10.19