From 52efec6a8357e19b40bb29dac9bfaebc00830539 Mon Sep 17 00:00:00 2001 From: Junyoung Kim Date: Tue, 23 Apr 2024 00:29:15 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[create/junyoung]=204=EC=A3=BC=EC=B0=A8=20?= =?UTF-8?q?=EB=B0=9C=ED=91=9C=20=EC=9E=90=EB=A3=8C=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...50\355\205\215\354\212\244\355\212\270.md" | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 "week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" diff --git "a/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" "b/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" new file mode 100644 index 0000000..58eda0f --- /dev/null +++ "b/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" @@ -0,0 +1,169 @@ +# Chapter 03. 영속성 컨텍스트 + +## JPA에서 가장 중요한 2가지 +- 객체와 관계형 데이터베이스 매핑 +- **영속성 컨텍스트** + +> 영속성 컨텍스트를 이해하면 JPA가 내부적으로 어떻게 동작하는지 알 수 있다. + + +## 3.1 엔티티 매니저 팩토리와 엔티티 매니저 +엔티티 매니저는 엔티티를 저장하고, 수정하고, 삭제하고, 조회하는 등 엔티티와 관련된 모든 일을 처리한다. + + + +> 웹 애플리케이션 + +![image](https://user-images.githubusercontent.com/43429667/75623964-107c8d00-5bf3-11ea-8220-642d7daec106.png) + +사진을 보면 하나의 EntityManagerFactory에서 다수의 EntityManager를 생성했다. + + EntityManager1은 아직 데이터베이스 커넥션을 사용하지 않는데, +엔티티 매니저는 데이터베이스 연결이 꼭 필요한 시점까지 커넥션을 얻지 않는다. + +EntityManager2는 커넥션을 사용 중인데 보통 트랜잭션을 시작할 때 커넥션을 획득한다. + + + + +## 3.2 영속성 컨텍스트란? + +JPA를 이해하는 데 가장 중요한 용어는 **영속성 컨텍스트**이다. 이것을 해석하면 +'**엔티티를 영구 저장하는 환경**'이라는 뜻이다. 엔티티 매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 +엔티티를 보관하고 관리한다. + +`em.persist(member);` + +엔티티 메니져에서 펄시스트를 호출해서 엔티티를 넣으면 DB에 저장하는 것이라고 배웠는데 + +실제로는 persist() 메서드는 **엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장**한다. + +영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 만들어진다. 그리고 엔티티 매니저를 통해서 영속성 컨텍스트에 접근, 관리할 수 있다. + + + + +## 3.3 엔티티의 생명주기 + +엔티티에는 4가지 상태가 존재한다. + +- **비영속**new/transient: 영속성 컨텍스트와 전혀 관계가 없는 상태 +- **영속**managed: 영속성 컨텍스트에 저장된 상태 +- **준영속**detached: 영속성 컨텍스트에 저장되었다가 분리된 상태 +- **삭제**removed: 삭제된 상태 + +> 생명주기 + +![image](https://user-images.githubusercontent.com/43429667/75624473-c053f980-5bf7-11ea-9e59-fca8a06c67bb.png) + + + + + +- #### **비영속** + + 엔티티 객체를 생성했다. 지금은 영속 컨텍스트와 전혀 관계가 없는 상태이다. + 따라서 영속성 컨텍스트나 데이터베이스와는 전혀 관련이 없다. 이것을 **비영속 상태**라 한다. + + ```java + // 객체를 생성한 상태(비영속) + Member member = new Member(); + member.setId("member1"); + member.setUsername("회원1"); + ``` + + > *em.persist() 호출 전, 비영속 상태* + + ![image](https://user-images.githubusercontent.com/43429667/75624520-3f493200-5bf8-11ea-9663-3413f154802c.png) + + + +- #### 영속 + + 엔티티 매니저를 통해서 엔티티를 영속성 컨텍스트에 저장했다. + 이렇게 **영속성 컨텍스트가 관리하는 엔티티를 영속 상태**라 한다. +이제 `member` 엔티티는 비영속 상태에서 영속 상태가 되었다. + **결국 영속 상태라는 것은 영속성 컨텍스트에 의해 관리된다는 뜻이다.** 그리고 em.find()나 jpql을 사용해서 조회한 엔티티도 영속성 컨텍스트가 관리하는 영속 상태이다. + +``` java +Member member = new Member(); +member.setId("member1"); +member.setUsername(“회원1”); +EntityManager em = emf.createEntityManager(); +em.getTransaction().begin(); +//객체를 저장한 상태(영속) +em.persist(member); + ``` + + > * em.persist() 호출 후, 영속 상태* + + ![image](https://user-images.githubusercontent.com/43429667/75624603-3573fe80-5bf9-11ea-97ab-fe42655bf5d9.png) + + + +- #### 준영속 + + 영속성 컨텍스트가 관리하던 영속 상태의 엔티티를 영속성 컨텍스트가 관리하지 않으면 준영속 상태가 된다. + 특정 엔티티를 준영속 상태로 만들려면 em.detach()를 호출하면 된다. em.close()를 호출해서 영속성 컨텍스트를 닫거나 + em.clear()를 호출해 영속성 컨텍스트를 초기화해도 영속성 컨텍스트가 관리하던 영속 상태의 엔티티는 준영속 상태가 된다. + + ```java + // 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태 + em.detach(member); + ``` + + + +- #### 삭제 + + 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다. + + ```java + // 객체를 삭제한 상태(삭제) + em.remove(member); + ``` + + + +## 3.4 영속성 컨텍스트의 특징 + +- **영속성 컨텍스트와 식별자 값** + + 영속성 컨텍스트는 엔티티를 식별자 값@Id로 테이블의 기본 키와 매핑한 값으로 구분한다. 따라서 **영속 상태는 식별자 값이 반드시 있어야 한다.** 식별자 값이 없으면 예외가 발생한다. + +- **영속성 컨텍스트와 데이터베이스 저장** + + 영속성 컨텍스트에 엔티티를 저장하면 이 엔티티는 언제 데이터베이스에 저장될까? + JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영하는데 + 이것을 플러시flush라 한다 + +- **영속성 컨텍스트가 엔티티를 관리할 때의 장점** + + - 1차 캐시 -> 현업에서 크게 성능적인 이점은 없다. + + - 동일성 보장 + ```java +Member a = em.find(Member.class, "member1"); +Member b = em.find(Member.class, "member1"); +System.out.println(a == b); //동일성 비교 true +``` + - 트랜잭션을 지원하는 쓰기 지연 + +![img](https://user-images.githubusercontent.com/43429667/75877743-b5999e80-5e5b-11ea-8b72-cfc347d41e5a.png) + + - 변경 감지 + +![img](https://user-images.githubusercontent.com/43429667/75891382-0bc60c00-5e73-11ea-8c0d-70ecfb20e4ee.png) +1. JPA는 commit을 하면 엔티티와 스냅샷을 비교한다. +2. 엔티티와 스냅샷을 비교하여 변경된 엔티티를 찾는다. +3. 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소에 보낸다. + +4. 쓰기 지연 저장소의 SQL을 데이터베이스에 보낸 후에 데이터베이스 트랜젝션을 커밋한다. +> JPA는 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해두는데 이것을 `스냅샷`이라고 한다. + - 지연 로딩 + + + + + + From 7fdc6fe55ce2eeb3c031aeaddc9eb258e163d3d5 Mon Sep 17 00:00:00 2001 From: Junyoung Kim Date: Tue, 23 Apr 2024 00:33:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[update/junyoung]=204=EC=A3=BC=EC=B0=A8=20?= =?UTF-8?q?=EB=B0=9C=ED=91=9C=20=EC=9E=90=EB=A3=8C=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...354\273\250\355\205\215\354\212\244\355\212\270.md" | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git "a/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" "b/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" index 58eda0f..feccbea 100644 --- "a/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" +++ "b/week04/\354\230\201\354\206\215\354\204\261 \354\273\250\355\205\215\354\212\244\355\212\270.md" @@ -34,7 +34,7 @@ JPA를 이해하는 데 가장 중요한 용어는 **영속성 컨텍스트**이 `em.persist(member);` -엔티티 메니져에서 펄시스트를 호출해서 엔티티를 넣으면 DB에 저장하는 것이라고 배웠는데 +엔티티 메니저에서 펄시스트를 호출해서 엔티티를 넣으면 DB에 저장하는 것이라고 배웠는데 실제로는 persist() 메서드는 **엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장**한다. @@ -47,10 +47,10 @@ JPA를 이해하는 데 가장 중요한 용어는 **영속성 컨텍스트**이 엔티티에는 4가지 상태가 존재한다. -- **비영속**new/transient: 영속성 컨텍스트와 전혀 관계가 없는 상태 -- **영속**managed: 영속성 컨텍스트에 저장된 상태 -- **준영속**detached: 영속성 컨텍스트에 저장되었다가 분리된 상태 -- **삭제**removed: 삭제된 상태 +- **비영속** : 영속성 컨텍스트와 전혀 관계가 없는 상태 +- **영속** : 영속성 컨텍스트에 저장된 상태 +- **준영속** : 영속성 컨텍스트에 저장되었다가 분리된 상태 +- **삭제** : 삭제된 상태 > 생명주기