JPA에서 가장 중요한 2가지를 꼽으라면 다음과 같다.

영속성 컨텍스트란 JPA를 이해하는데 가장 중요한 용어로 “엔티티를 영구 저장하는 환경” 이라는 뜻으로 EntityManager.persist(entity); 를 사용하여 저장하면 DB에 바로 저장하는것 처럼 보이지만 사실은 EntityManager에 영속시기는 것이다. 따라서 영속성 컨텍스트는 논리적인 개념이라 눈에 보이지 않고, 엔티티 매니저를 통해서 접근을 할 수 있다.


준영속 —> em.detach(member);
삭제 —> em.remove(member);
em.persist(member); 를 실행하게 되면 1차 캐시에 저장이 된다.
그 후 Member findMember = em.find(Member.class, “member1”); 을 실행하면 DB에 접근해서 Member를 조회하는게 아니라 1차 캐시에서 조회를 해 오게 된다. 만약 1차 캐시에 정보가 없을 경우, DB를 조회하여 가져오고 1차 캐시에 저장한 후 반환 하게 된다.
다음 예시와 같이 영속 엔티티는 동일성이 보장된다.
ex)
Member a = em.find(Member.class, “member1”);
Member b = em.find(Member.class, “member2”);
System.out.println(a == b); //true

em.persist(memberA);
em.persist(memberB); 를 하게 되면 memberA와 B는 1차캐시에 들어가는 동시에 INSERT SQL이 생성되어 “쓰기 지연 SQL 저장소”에 저장된다. 그 후 transaction.commit(); 순간에 이 쿼리들이 DB로 날라가게 되고, DB에 커밋이 된다.
또한 1차 캐시에는 엔티티가 처음 1차캐시에 저장될 때, 스냅샷을 만들어 읽어 왔던 최초 모습을 저장한다. 이를 통해 데이터를 수정할 때, em.update(member)와 같은 코드가 있지 않아도 알아서 스냅샷과 비교해 변동이 있으면 마찬가지로 쓰기 지연 저장소에 UPDATE 쿼리를 저장한다.
플러시란 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것이다.
변경을 감지하면, 수정된 엔티티 쓰기 지연 SQL 저장소에 등록을 하고 등록, 수정, 삭제 쿼리를 데이터 베이스에 전송을 하게 된다. 이때 플러시 후 커밋을 하게 된다.
영속성 컨텍스트를 플러시 하는 방법에는 3가지 방법이 있다.
쿼리 실행 시 자동 호출이 되는 이유는 그렇게 하지 않으면, 데이터를 넣은 다음 바로 조회를 하면 1차캐시에만 있고 DB에는 없어서 읽어오지 못하기 때문이다.
또한 플러시 모드 옵션을 사용하여 플러시 시점을 조절할 수 있다.
—> em.setFlushMode(FlushModeType.COMMIT)
플러시는 영속성 컨텍스트를 비우지 않는다. 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화하며 트랜잭션이라는 작업 단위가 중요하다. (커밋 직전에만 동기화 하면 된다.)
준영속 상태란 영속 상태의 엔티티가 영속성 컨텍스트에서 분리가된 상태이다. 준영속 상태가 되면 영속성 컨텍스트가 제공하는 기능을 사용하지 못하게 된다.
준영속 상태로 만드는 방법