영속성 컨텍스트는 엔티티를 관리하기 위해 캐시를 사용한다. 캐시는 일종의 메모리 저장소로, 엔티티의 상태를 임시로 저장하고 관리한다. JPA 구현체(예: Hibernate)는 영속성 컨텍스트를 통해 엔티티의 생명주기를 관리하며, 엔티티의 변경 사항을 데이터베이스에 동기화한다.
영속성 컨텍스트의 캐시 기능은 다음과 같은 이점을 제공한다.
[package hellojpa;
import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence;
public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member member = new Member();
member.setId(4l);
member.setName("test");
em.persist(member);
// Member findMember = em.find(Member.class, 4l); // System.out.println("findMember.getId() = " + findMember.getId()); // System.out.println("findMember.getName() = " + findMember.getName()); System.out.println("findMember.getId() = " + member.getId()); System.out.println("findMember.getName() = " + member.getName());
member.setName("testUpdate");
// em.merge(member); // Member updatedMember = em.find(Member.class, 4l); // System.out.println("updatedMember.getId() = " + updatedMember.getId()); // System.out.println("updatedMember.getName() = " + updatedMember.getName());
System.out.println("updatedMember.getId() = " + member.getId());
System.out.println("updatedMember.getName() = " + member.getName());
em.remove(member);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}](https://willneiman.notion.site/package-hellojpa-import-javax-persistence-EntityManager-import-javax-persistence-EntityManagerFac-91b7e804c0a34d4a80aecf88f1b64cc3) 의 crud 코드 각 단계에 주석을 달아 설명하면 다음과 같다.
// 영속화 전, 그저 자바 객체인 상태
Member member = new Member();
member.setId(4l);
member.setName("test");
// 새로운 객체를 데이터베이스에 저장하려고 하며, 이때부터 EntityManager가 관리하기 시작한다.
// 영속성 컨텍스트에 객체를 넣어 관리하도록 함. (실제 데이터베이스에 저장은 커밋 시점에 발생)
em.persist(member);
// 영속화된 객체의 정보를 출력
System.out.println("member.getId() = " + member.getId());
System.out.println("member.getName() = " + member.getName());
// 영속화된 객체의 속성을 변경. 영속성 컨텍스트 내에서 변경 감지(dirty checking)가 발생.
member.setName("testUpdate");
// 변경된 객체의 정보를 출력. 다만 여기서는 그저 자바 객체의 변경일 뿐이다.
System.out.println("member.getId() = " + member.getId());
System.out.println("member.getName() = " + member.getName());
// 영속성 컨텍스트에서 객체를 삭제하도록 함. 실제 데이터베이스에서 삭제는 커밋 시점에 발생
// em.remove를 호출한 시점에서 영속성 컨텍스트는 이 객체를 관리하지 않는다. (준영속 상태)
em.remove(member);
// 만약 여기서 remove()를 사용하지 않는다면 dirty checking에 의해 UPDATE문이 호출됨.
// 트랜잭션 커밋 시점. 영속성 컨텍스트가 실제 데이터베이스에 변경 사항을 반영한다.
// 객체가 영속성 컨텍스트에서 제거되었기에 실제 데이터베이스에 아무런 변화가 없다.
// 영속성 컨텍스트 내부에서 발생한 insert와 delete는 데이터베이스와 동기화될 때 적용되며,
// 이 경우 실제로 데이터베이스에는 아무런 변화가 없어진다.
tx.commit();