당니의 개발자 스토리

영속성 컨텍스트 1 본문

스프링/자바 ORM 표준 JPA 프로그래밍 - 기본편

영속성 컨텍스트 1

clainy 2024. 5. 25. 22:56

영속성 컨텍스트 1

이번 시간에는 JPA의 내부구조가 어떻게 동작하는지 약간의 이론적인 내용에 대해서 알아보겠습니다.

제목은 영속성 관리구요.

JPA를 이해하려면 영속성 컨텍스트라는 것을 이해해야 됩니다. 제가 정말 쉽게 설명해 드리겠습니다.

JPA에서 가장 중요한 것 두가지, JPA를 공부하는데 가장 중요한 것 두가지를 뽑으려고 하면 객체랑 관계형 데이터베이스를 어떻게 맵핑할 거냐 하는 이 맵핑의 관점은 약간 정적인 거죠.

DB를 어떻게 설계하고 객체를 어떻게 설계해서 이거를 중간에서 어떻게 JPA를 맵핑해서 쓸 거야? 하는 이 맵핑, 그러니까 약간 설계와 관련된 이 부분은 약간 정적인 거죠.

그리고 또 하나 중요한 게 실제 JPA가 내부에서 도대체 어떻게 동작해? 라는 부분이 영속성 컨텍스트와 관련이 되어있는데요. 영속성 컨텍스트를 명확하게 이해하면 JPA가 내부적으로 어떻게 동작하는지 이해하실 수 있을 거에요.

이번 시간에는 영속성 컨텍스트에 대해서 알아보는 시간을 가지겠습니다.

이제 jpa 를 보통 쓰시게 되면 이미 말씀 한번 드렸지만 엔티티 매니저 팩토리와 엔티티 매니저에 대해서 먼저 이해를 해야 됩니다. 예를 들어서 이제 웹 어플리케이션 개발한다고 하면, 여기 보시면 이제 엔티티 매니저 팩토리, 우리가 지난 시간에 했던 그 엔티티 매니저 팩토리를 통해서 고객의 요청이 올 때마다 엔티티 매니저를 생성을 합니다.

여기 보시면 엔티티 매니저1, 또 새로운 고객의 요청이 오면 또 엔티티 매니저2를 생성하고, 이 엔티티 매니저는 내부적으로 데이터베이스 커넥션을 사용해서 DB를 사용하게 됩니다.

그러면 영속성 컨텍스트라는 건 도대체 뭔가.

우선 JPA를 이해하는데 가장 중요한 용어입니다.

굳이 이걸 한국어로 번역을 해보면 이제 '엔티티를 영구 저장하는 환경'이라는 뜻이에요. 컨텍스트가 환경, 문맥 이런 뜻이니까요.

그래서 이제 엔티티 매니저에서 persist를 호출해서 엔티티를 집어넣으면 우리가 처음 배웠던 거는 persist를 하면 이 엔티티 객체, Member나 Team이나 이런 객체를 DB에 저장하는구나 라고 이제 배웠는데요. 실제로는 이제 좀 깊은 내용들이 있습니다.

persist는 사실 DB에 저장한다는 게 아니라, 영속성 컨텍스트를 통해서 이 엔티티라는 걸 영속화한다는 뜻인데요. 더 정확히 말씀드리면 이 persist 메서드는 사실 DB에 저장하는 게 아니라, 엔티티를 영속성 컨텍스트라는 데 저장한다는 겁니다.

감이 안오죠? 일단 더 지나가보겠습니다.

엔티티 매니저? 영속성 컨텍스트?

영속성 컨텍스트는 약간 논리적인 개념이에요. 그리고 이게 눈에 보이지 않아요. 엔티티 매니저는 여러분이 쓰셨던 em.persist 했던 거죠. 그럼 영속성 컨텍스트 라는 건 뭐지?

자 엔티티 매니저를 통해서 영속성 컨텍스트에 접근합니다.

일단 이전 시간에 제가 보여드렸던 것은 엔티티 매니저를 생성하면, 엔티티 매니저 안에 1:1로 영속성 컨텍스트가 생성이 됩니다. 엔티티 매니저 하나 당 영속성 컨텍스트가 하나 생성되는 거죠.

그러니까 쉽게 말씀드리면 엔티티 매니저 안에 영속성 컨텍스트라는 눈에 보이지 않는 공간이 생기다고 이해하시면 되고요.

밑에 J2EE 이건 넘어가겠습니다. 나중에 스프링 프레임워크까지 해야 이해할 수 있어요.

자 그럼 일단 여기까지 해놓고 약간 이해가 안 돼도 그냥 들으시면 돼요.

그 다음에 엔티티는 생명 주기가 있습니다. 저희가 em.persist 라고 했던 거 기억나시죠? 그걸 하지 않은 그냥 최초의 Member 객체를 생성한 상태, 이거는 new 상태라고 그러고요. 비영속이라고 합니다. 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태예요.

제가 방금처럼 entityManager.persist 라고 하면 member가 영속 상태라는 게 됩니다. 영어로는 managed 상태라 그러고요. 영속성 컨텍스트에 관리되는 상태입니다.

그리고 이제 뭐 준영속, 삭제 이런게 있는데 이건 이렇게 표만 보고 설명 드리면 안 다가와요. 그래서 제가 뒤에 코드로 쭉 설명을 드리겠습니다.

뭐 생명주기 이런거 있는데 이거는 한번 보시면 되구요.

자 제일 먼저 비영속.

비영속 상태라는 건 뭐냐면 Member 객체를 생성을 했어요. 그리고 내가 엔티티 매니저에 아무것도 안 넣었어요. 생성만 한 상태죠. 코드를 보시면, 이렇게 그냥 세팅만 한 상태예요. 이건 내가 jpa에 전혀 관계없이 그냥 딱 객체만 생성한 거죠. 이거는 JPA랑 전혀 관계없는 상태이기 때문에 이런걸 비영속 상태 라고 합니다.

그러면 영속상태 라는 건 뭐냐면,

아까 제가 말씀드린 것처럼 EntityManager 안에는 영속성 컨텍스트가 있다고 했죠. 이렇게 Member 객체를 생성을 한 다음에 엔티티 매니저를 얻어와서 이 엔티티 매니저에 persist 해서 Member 객체를 딱 집어 넣으면, 이 엔티티 매니저 안에 있는 영속성 컨텍스트 라는 거에다가 이 Member 객체가 들어가면서 영속 상태가 됩니다.

자 한번 보여드릴게요. 영속상태가 뭔지 코드로 보면,

이 코드는 지우고,

이렇게 세팅하면 여기까지는 무슨 상태냐면 그냥 아무 상태도 아닌 거예요.

자 그러면 em.persist 해서 이 member를 딱 집어넣으면 여기서부터 이제 영속 상태가 됩니다.

영속 상태는 이 엔티티 매니저 안에 있는 영속성 컨텍스트라는 데를 통해서 이 Member가 관리가 된다는 뜻입니다.

자 이전에는 em.persist(member) 하면 member가 DB에 저장이 되는 것처럼 설명을 드렸는데 사실은 이때 DB에 저장되지 않습니다.

그럼 언제 DB에 저장되는가? 는 뒤에 한번 설명을 드릴게요.

진짜 DB에 저장이 안 됐는지 출력을 해서 확인하겠습니다.

만약에 em.persist(member)하는 이 때, DB에 저장이 된다면 SQL이 날라가겠죠? 이렇게 하고 실행해보면,

before랑 after 사이에 아무것도 없죠. 그런데 뒤에 보면 insert 쿼리가 날라가긴 했어요. 이 Before랑 After랑 전혀 관계없이 뒤에서 insert 쿼리가 날라갔어요.

그니까 딱 바로 결론부터 말씀드리면, 이 영속 상태가 된다고 해서 바로 DB에 쿼리가 날라가는 게 아니에요.

언제 쿼리가 날라가냐면 트랜잭션을 commit 하는 시점에 이 영속성 컨텍스트에 있는 DB에 쿼리가 날라가게 됩니다.

뒤에 아주 자세하게 한번 설명 드릴게요. 그럼 이제 잠깐 넘어가서 준영속이랑 삭제 상태는 뭐냐면,

이 엔티티 매니저에서 Detach 라고 하면 영속성 컨텍스트에서 다시 지웁니다. 그럼 다시 관계가 없어지는 거구요.

remove는 뭐냐면 실제 DB에 삭제를 요청하는 상태라고 보시면 됩니다. 어떤 데이터베이스에서 실제 영구 저장된 객체를 지우겠어! 라는 상태라고 보시면 됩니다.

자 그러면 지금 제가 막 영속성 컨텍스트 설명을 드렸는데, 뭔가 알 것 같기도 하고 모를 것 같기도 한 분들도 있을 거예요. '왜 이렇게 이상한 메커니즘을 두지?' 라고 생각할 수 있는데, 애플리케이션이랑 데이터베이스 사이에 영속성 컨텍스트 라고 하는 중간 계층이 하나 있는 거에요. 영속성 컨텍스트 라는 중간 계층이 있으면 큰 이점을 얻어내는 게 있는데

쭉 이런게 있습니다. 바로 설명드리기 보다 뒤에서 더 자세히 말씀드릴게요.

이렇게 중간에 있으면 좋은 게 예를 들면 이런 거예요.

우리가 버퍼링을 할 수도 있고, 캐싱을 할 수도 있고 하는 이점들을 누릴 수가 있죠. 이제 영속성 컨텍스트를 통해서 이런 이점들을 누릴 수 있는데요.

이것에 대해서 다음 시간에 하나씩 설명을 드리겠습니다.

'스프링 > 자바 ORM 표준 JPA 프로그래밍 - 기본편' 카테고리의 다른 글

플러시  (0) 2024.05.26
영속성 컨텍스트 2  (0) 2024.05.26
Hello JPA - 애플리케이션 개발  (0) 2024.05.25
Hello JPA - 프로젝트 생성  (0) 2024.05.25
JPA 소개  (0) 2024.05.24