영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
Member member = new Member();
member.setId("memberA");
member.setName("범철");
Member member = new Member();
member.setId("memberA");
member.setName("범철");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
/* 영속성 컨텍스트에 영속화 하는 것 */
em.persist(member);
/* 특정 객체를 영속성 컨텍스트에서 분리하는 것 */
em.detach(member);
/* 영속성 컨텍스트 전체를 비우는 것 */
em.clear();
/* 영속성 컨텍스트를 종료하는 것 */
em.close();
삭제된 상태
em.remove(member);
영속성 컨텍스트는 자체적으로 캐시를 가지고 있다.
영속성 컨텍스트에 영속화(managed) 되어있는 객체에 대한 조회시 캐시에서 가져온다.(시간적인 이점 < 구조적로 인한 다른 이점)
영속화 되는 두가지 경우
em.persist()로 영속화
캐시에 등록되어 있지 않을 때, em.find()하는 경우
em.persist()는 영속화 하는 과정이고, DB에 저장하는 것은 아니다.
영속화되어 관리되는 객체들은 반드시 flush과정을 거처야 실제 DB에 반영된다.
(정확히는 flush 이후 commit되어야 저장된다.)
영속화를 하면 2가지이 수행된다.
즉, 쓰기가 지연되었다가 flush로 인해 한번에 반영된다.
동작
commit이 되면 flush 과정으로 인해 쌓인 쿼리가 수행된다.
flush이후 실제 DB에 저장하는 commit이 수행된다.
em.find()를 통해서 가져온 객체를 수정한 뒤 em.persist()를 해야 하는가?
변경 감지가 어떻게 일어나는가?
쓰기 지연 저장소
에 저장한다.쓰기 지연 SQL 저장소
에 있는 쿼리가 수행한다.개발자가 직접 호출
em.flush()를 통해 직업 flush를 수행할 수 있다.
(쿼리가 수행된다.)
트랜잭션 커밋 - 자동호출
트랜잭션이 commit되면 자동으로 flush를 수행한다.
JPQL 쿼리 수행 - 자동호출
JPQL쿼리가 수행되면 디폴트로 flush가 수행된다.
옵션으로 지정이 가능하지만 거의 사용하지 않는다.
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 중간에 JPQL 실행 --> flush 자동 수행!
// 지금까지 영속화로 저장된 모든 쿼리문이 수행되게 된다
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
Flush는 쿼리를 전송하는 역할이고 commit은 내부죽으로 flush를 수행한 뒤 트랜잭션을 끝내는 역할이다.
즉, flush로 전송된 쿼리는 롤백할 수 있지만 commit은 트랜잭션을 끝내므로 rollback할 수 없다.