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(101L);
member.setName("HelloJPA");
em.persist(member);
Member findMember = em.find(Member.class, 101L);
System.out.println("findMember.id = " + findMember.getId());
System.out.println("findMember.name = " + findMember.getName());
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
결과를 보면 persist 까지 하고 find를 했는데 select 쿼리를 쓰지 않았다. 결론부터 말하면 DB에 접근하기 전에 먼저 영속상태가 된 PK 값이 101L인 값을 가져왔기 때문인다.
persist는 DB에 저장하는 것이 아닌 1차 캐시에 저장하는 것이다. 즉, persist는 쿼리를 날리는 것이 아닌 데이터를 영속상태로 만드는 것이다. 영속 상태로 만든다는 것은 영속성 컨텍스트에 데이터를 저장한다는 것.
그림을 보면 persist를 하게 되면 아래 그림이 된다.
이 그림에서 보면 데이터가 DB에 저장되지 않았다는 것이다. 즉 1차 캐시에 저장이 된다.
다음으로 이 상태에서 find를 하게 된다면?
DB를 확인하기 전에 1차 캐시를 먼저 확인하고 같은 PK를 가진 속성을 확인하기에 select 쿼리를 날리지 않는다.
참고로 commit 할 때 insert 쿼리를 날리게 됨.(DB 저장)
그리고 EntityManager를 close하게 되면 기존 캐시는 사라지게 된다.
위의 내용을 좀 더 명확하게 확인하기 위해서 코드를 아래와 같이 바꿔보았다.
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Member findMember1 = em.find(Member.class, 101L);
Member findMember2 = em.find(Member.class, 101L);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
위의 내용대로라면 select 쿼리는 findMemeber1을 호출할 때 한 번만 날릴 것이다. 그 이유는 select하고나서 데이터를 1차 캐시에 저장하기 때문이다.
결과를 보면
역시 select 쿼리는 한 번만 날렸다.
[ JPA ] 양방향 연관관계(1) - mappedBy (0) | 2022.01.07 |
---|---|
[ JPA ] 단방향 연관관계 (0) | 2021.12.30 |
[ JPA ] @Entity (0) | 2021.12.19 |
[ JPA ] JPA로 DB 데이터 삽입 (0) | 2021.12.16 |
[ JPA ] JPA 구동 방식 (0) | 2021.12.14 |