영속성 컨텍스트는 엔티티를 영구 저장하는 환경이다.
em.persist(entity)
위 코드를 실행하면 entity 객체가 바로 DB 에 입력이 되는 것이 아니라, 영속성 컨텍스트로 등록이 되는 것이다.
EntityManager를 통해서 영속성 컨텍스트에 접근할 수 있다.
영속 상태란? 1차 캐시에 엔티티가 등록되어 관리되는 상태이다. 이 상태에서 같은 객체를 다시 한번 조회하게 되면, 굳이 DB에 select문을 보내서 값을 찾아오는 것이 아니라 1차 캐시상에서 값을 바로 가져온다. 그렇기 때문에 성능상의 이점도 있고, 마치 JAVA에서의 컬렉션에서 값을 꺼내오는 것처럼 엔티티의 동일성을 보장받게 된다.
데이터베이스에 엔티티 조회 시, 1차 캐시에 찾는 객체가 있는지 확인 후 없을 경우 DB에서 select 문을 통해 찾아온다.
1차 캐시로부터 찾은 객체는 서로 동일함이 보장된다.
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true
영속성 컨텍스트는 buffer의 역할을 한다. 변경사항이 생기면 쓰기 지연 SQL 저장소에 모아놨다가 트랜잭션을 커밋할 때 flush 되어 DB 에 반영된다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
영속성 컨텍스트는 flush 할 때 이전의 상태를 스냅샷(snapshot)으로 저장해놓고 변경사항을 체크해 업데이트를 해준다.
em.setFlushMode(FlushModeType.COMMIT)
영속 상태의 엔티티가 영속성 컨텍스트에서 분리됬을 때(detached)의 상태이다.
영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
준영속 상태의 엔티티를 변경해도 변경 감지가 작동하지 않아서 DB에 반영되지 않는다.