1일1배움/JPA (김영한 님)
2023.12.21 [entityManager.find() 는 commit() 전까지 쓰기 지연 SQL 저장소에 쿼리를 저장할까?]
kim chan jin
2023. 12. 23. 17:58
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"); // persistence.xml
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
System.out.println("=== find() === ");
Member member = em.find(Member.class, 1L); // 영속
System.out.println("=== find() === ");
System.out.println("=== setName() ===");
member.setName("AAA");
System.out.println("=== setName() ===");
System.out.println("=== detach() ===");
em.detach(member); // 준영속
System.out.println("=== detach() ===");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
=== find() ===
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
=== find() ===
=== setName() ===
=== setName() ===
=== detach() ===
=== detach() ===
아니다.
쓰기 지연 SQL 저장소는 객체의 변경사항을 트랜잭션 커밋으로 DB에 반영하기 전에 쿼리를 모아두는 것이다.
em.find() 는 객체에 변경사항을 만들지 않기 때문에 쓰기 지연 SQL 저장소에 쿼리를 저장하지 않는다.
예를 들어, em.find(Member.class, 1L) 메서드 호출하여 멤버 객체 memberA를 검색한다면
가장 먼저 1차 캐시를 검색하고 만약 1차 캐시에 멤버 객체 memberA가 존재한다면 DB 에 쿼리를 날릴 필요없이 바로 멤버 객체 memberA를 반환하고
만약 1차 캐시에 DB에서 검색된 멤버 객체 A가 존재하지 않다면 DB 에 쿼리를 날려 멤버 객체를 가져와서 엔티티 매니저의 영속성 컨택스트의 1차 캐시 테이블에 저장한다.
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"); // persistence.xml
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
System.out.println("=== find() === ");
Member member = em.find(Member.class, 1L); // 영속
System.out.println("=== find() === ");
System.out.println("=== setName() ===");
member.setName("AAA");
System.out.println("=== setName() ===");
System.out.println("=== detach() ===");
// em.detach(member); // 준영속
System.out.println("=== detach() ===");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
=== find() ===
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
=== find() ===
=== setName() ===
=== setName() ===
=== detach() ===
=== detach() ===
Hibernate:
/* update
hellojpa.Member */ update
Member
set
name=?
where
id=?