1차 캐시를 경유하는 것에 의한 라이프사이클을 실습으로 확인합니다.
엔티티의 상태
상태는 빠르게 3가지 정도를 언급해주셨습니다. 이것도 출처에 따라 말이 좀 다른 거 같긴 한데... 의미하는 바는 얼추 비슷해보입니다. 용어보다 중요한 건 (1)관리되느냐 (2)언제 반영되느냐 (3)반영되긴 하느냐 정도인 것 같네요.
강의에서는 이런 용어들의 명확한 정의에 대해서 다루지는 않으셨습니다. 그냥 비슷한 용어가 영어로도 이런 종류가 있으니 잘 기억해두라 정도였던 것 같네요.
인터넷을 검색해보면 출처를 알 수 없는 다이어그램들이 많이 나옵니다. 설명도 출처가 같이 명시되지 않은 경우가 많구요. 결국 원류를 찾아 거슬러올라가다보면 Jakarta Persistence (= JPA) 문서를 만나게 됩니다. 그러니까, hibernate 같은 구현체의 얘기가 아니라 JPA 스펙 자체의 용어들이라는거죠.
https://jakarta.ee/specifications/persistence/3.0/jakarta-persistence-spec-3.0.html#a1929
jakarta 3.0 문서의 3장에서 EntityManager 관련해서 개요를 많이 설명해주는 것 같습니다. 시간날 때 다 읽어보면 좋겠지만 시간은 항상 녹록치 않죠.
- new: "아직 안 등록된": 영속 ID가 없고, Persistence Context에도 안 묶여있음
- managed: "관리되는": 영속 ID도 있고, Persistence Context에도 묶여있음
- detached: "반영되지 않을": 영속 ID는 있지만, Persistence Context에는 안 묶여있음
- removed: "곧 삭제될" (영속 ID가 있고 Persistence Context에 묶여있음)
아 이거 표 각이네... 웹에서 표 잘 안 쓰려고 하는데...
엔티티의 상태 | Persistence Identity 엔티티를 구분지을 수 있는 ID 존재 |
Persistence Context DB에 영속시킬 대상에 포함되어 있음 |
new | X | X |
managed | O | O |
detached | O | X |
removed | O | O |
앞선 섹션을 대충 훑어봤는데, em의 일부 연산은 반드시 Transaction 에 묶여있는 Persistence Context의 상태여야 한다더라구요. 참고해야 할 거 같아서말이쥬.
The persist, merge, remove, and refresh methods must be invoked within a transaction context when an entity manager with a transaction-scoped persistence context is used. If there is no transaction context, the jakarta.persistence.TransactionRequiredException is thrown.
https://jakarta.ee/specifications/persistence/3.0/jakarta-persistence-spec-3.0.html#a1066
Transient 는 아예 영속대상으로 안 잡는 거 같네유. 앞에도 비슷한 말들이 좀 있구... "new" 랑은 다른 의미이긴 하지만 둘 다 영속 대상이 아니고 ID도 없는 건 같으니 강의에서 말씀하셨던 것처럼 비슷한 표현이라고 봐도 될 거 같네요.
The Transient annotation is ... 생략 ... It specifies that the property or field is not persistent.
https://jakarta.ee/specifications/persistence/3.0/jakarta-persistence-spec-3.0.html#transient-annotation
EntityManager의 메소드로 라이프사이클 확인
각설하고 다시 강의 내용으로 돌아와서. 사실 저것들이 거의 강의 내용이랑 매한가지이긴 한데요...
강의 내용에서는 EntityManager의 4가지 메서드에 detach 같은 걸 더해서 라이프사이클을 체험합니다. 위에 보셨던 4가지 있죠? persist, merge, remove, refresh 에 추가로 flush, detach 에 더해서 clear, close 같은게 있다 정도가 나왔습니다.
코드보다 노트에 필기한 내용이 더 나아보이네요. 그림으로 옮겨볼까...
- 앞선 강의에서 정리한 것처럼, @Transactional 이 끝나거나, flush 가 호출되거나 하면 Persistence Context의 변경 내역이 실제로 영속(DB에 반영)됩니다. 이 점은 유념.
- 아무리 주변이 @Transactional 로 감싸져있어도, 그 안에서 객체를 만든 건 그냥 객체를 만든겁니다. new 상태겠네요. DB에 반영될리가 없죠.
// 티스토리 신규 에디터가 저를 미워하네요. 죽어도 list 있는데에 pre랑 code는 못 넣어주겠다고... // 안 넣어주면 html 편집 아 귀찮은데 @Service class AccountService { @Transactional public putAccount() { Account account = new Acocunt(); account.setName("ohhhhh"); // Transaction 이 끝나도 아무 일도 일어나지 않습니다. } }
em.persist()
Make an instance managed and persistent.
em.persist() 로 new 상태인 객체를 Persistence Context에 넣을 수 있습니다. 트랜젝션이 끝나는 등의 상황이 되면 DB에 반영되겠죠. 예를 들자면
em.persist(acocunt);
account.setEmail("asdf@gg");
까지만 하면 DB에는 persist 이후의 나중에 바뀐 email 까지는 반영되지 않겠죠. 반영 됩니다. managed 상태가 되었기에...
em.detach()
Remove the given entity from the persistence context, causing a managed entity to become detached. Unflushed changes made to the entity if any (including removal of the entity), will not be synchronized to the database. Entities which previously referenced the detached entity will continue to reference it.
em.detach() 를 하면 Persistence Context에 있는 managed 상태의 객체를 더 관리 안 되게 만들 수 있습니다. 가령...
em.detach(account);
account.setEmail("asdf@gg")
를 하면 새로 변경한 이메일은 반영되지 않습니다.
em.merge()
Merge the state of the given entity into the current persistence context.
em.merge() 로 detached 상태였던 객체를 다시 Persistence Context에 반영할 수 있습니다. managed 가 된다는 말이겠죠. 가령...
em.detach(acocunt);
account.setEmail("asdf@gg");
em.merge(acocunt);
반영...되겠죠?
em.clear() 등
em.clear() 는 모든 Persistence Context의 객체를 detach 한다고 하네요.
em.close() 는 문서를 봐서는 아예 닫아버리는 것 같습니다. 이건 필요할 때 다시봐야...
요점은 라이프타임을 신경쓰자는 것
강의에서는 예시 위주로 봤지, 문서까지 자세히 살펴보진 않았습니다. 요점은 객체가 어떻게 Persistence Context 에서 관리되는지 잘 인지한 상태에서 짜야지 좋겠다는 거였구요. 이것과 관련한 오해 때문에 트러블이 발생하는 경우도 있었다니 ㅎㅎ
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스: https://bit.ly/37BpXiC
#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #한번에끝내는JavaSpring웹개발마스터초격차패키지Online
강의는 15분만에 본 거 같은데 정리하는데 1시간은 되는 거 같아
'FastCampus - 한번에 끝내는 Java|Spring 웹 개발 > 04 JPA' 카테고리의 다른 글
JPA Ch 7 영속성 - 트랜젝션 매니저 (3~4) - 패스트캠퍼스 챌린지 33일차 (0) | 2022.02.25 |
---|---|
JPA Ch 7 영속성 - 트랜젝션 - 패스트캠퍼스 챌린지 32일차 (0) | 2022.02.24 |
JPA Ch 7 영속성 - 엔티티 캐시 (1차 캐시) - 패스트캠퍼스 챌린지 30일차 (0) | 2022.02.22 |
JPA Ch 7 영속성 - 개요 & 리얼 DB - 패스트캠퍼스 챌린지 29일차 (0) | 2022.02.21 |
JPA Ch 6 릴레이션 M:N - 패스트캠퍼스 챌린지 28일차 (0) | 2022.02.20 |