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=?