본문 바로가기

Programming/과거포스팅

[JPA] - 영속성 컨텍스트(persistence context) 와 엔티티의 생명주기

영속성 컨텍스트(persistence context)


JPA를 이해하는데 가장 중요한 용어는 영속성 컨텍스트(persistence context)다. 세미나에서 김영한님이 강조하신 부분이기도한데 이 부분을 정확히 이해하고 있어야 JPA를 잘 사용할 수 있다. 영속성 컨텍스트는 우리말로 변경하지면 '엔티티를 영구적으로 저장하는 환경'이라는 뜻이다.

앞의 포스팅에서 설명했더니 무조건 엔티티에 set한다고 저장이 되거나 하는 것이 아니었다. 해당 엔티티가 매니저를 통해서 트렌젝션을 시작해야만 데이터베이스와 커넥션을 맺고 해당 엔티티가 영속성을 가지게 된다. 그래야만 set을 하더라도 수정이 된다. 영속성을 가진다는 말은 이 엔티티가 현재 데이터 베이스와 연결되어 있는 것과 동일한 상태라고 보면 된다. 엔티티매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하는데 이 때가 영속성을 가지는 상태라고 보면 된다. 영속성 컨텍스트는 우리가 사용하거나 조작할 수 있는 범위가 아니기 때문에 어떠한 개념인지만 파악하고 있으면 된다.


영속성 컨텍스트의 특징

1. 영속성 컨텍스트와 식별자 값 - 영속성 컨텍스트는 엔티티를 식별자 값(id)로 구분하기 때문에 식별자 값이 반드시 있어야 한다.

2. 영속성 컨텍스트가 데이터베이스에 저장되는 시점 - 영속성 컨텍스트에 엔티티를 저장하면 바로 데이터베이스에 저장 되는 것이 아니라. 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영한다.




엔티티의 생명주기

엔티티에는 4가지 상태가 존재하는데 이것에 대해서 정확히 알고 있어야 한다.


String id = "id1"; Member member = new Member(); member.setId(id); member.setUsername("돈일"); member.setAge(2); //등록 em.persist(member); //수정 member.setAge(20); //한건 조회 Member findMember = em.find(Member.class, id); System.out.println("findMember=" + findMember.getUsername() + ", age=" + findMember.getAge()); //여러건 조회 List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList(); System.out.println("members.size=" + members.size()); //삭제 em.remove(member);


위의 코드에는 엔티티의 생명주기가 모두 담겨져 있다.
엔티티의 생명주기는 4가지가 있는데
1. 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태
2. 영속(managed) : 영속성 컨텍스트에 저장된 상태
3. 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
4. 삭제(removed) : 삭제된 상태


비영속상태

Member member = new Member();
member.setId(id);
member.setUsername("돈일");
member.setAge(2);

위의 코드를 보면 Member라는 객체를 생성하고 아직 저장을 하지 않은 상태이다. 트랜잭션 내에 있지만 엔티티 매니저와 아무런 관계가 없다. 그렇기 때문에 영속성 컨텍스트와도 아무 관련이 없는 상태이다. 이러한 상태를 비영속 상태라고 한다.


영속상태

em.persist(member);
Member findMember = em.find(Member.class, id);

엔티티 매니저를 통해서 데이터베이스에 저장하거나 데이터 베이스에서 조회한 엔티티는 영속상태라고 보면 된다. 이 경우 엔티티는 엔티티매니저가 영속성 컨테이너에 저장한다. 영속상태의 엔티티에서 수정이 일어나면 실제 데이터 베이스도 없데이트가 된다.


준영속상태

em.detach(member);

영속상태의 엔티티를 영속성 컨테이너가 관리하지 않으면 준영속 상태가 된다. 그리고 em.close()와 같이 영속성 컨텍스트를 닫거나 초기화를 해도 영속 상태의 엔티티는 준영속 상태가 된다. 


삭제

em.remove(member);

엔티티 객체를 영속성 컨텍스트와 데이터베이스에서 삭제한다.