JPA

두주·2024년 1월 18일
0

TIL

목록 보기
34/58

Entity의 lifecycle

  • 비영속 (new/transient)
    -> 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

  • 영속 (managed)
    -> 영속성 컨텍스트에 관리되는 상태

  • 준영속 (detached)
    -> 영속성 컨텍스트에 저장되었다가 분리된 상태

  • 삭제 (removed)
    -> 삭제된 상태

    영속성 컨텍스트의 이점

  • 1차 캐시

  • 동일성(identity) 보장

  • 트랜잭션을 지원하는 쓰기 지연 (Transactional write-behind)

  • 변경 감지 (Drity Checking)

  • 지연 로딩 (Lazy Loading)

엔티티 조회, 1차 캐시

//엔티티를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

//엔티티를 영속
//em = entity manager
em.persist(member);

    fun practice1(){
        //JPA 특성을 가지고 있다.
        val emf = Persistence.createEntityManagerFactory("hello")
        val em = emf.createEntityManager()

        // 비영속 상태이다.
        val member = Member()
        member.id = 101L
        member.title = "테스트맨"

        // transaction
        val transaction = em.transaction
        transaction.begin()

        println("BEFORE") // before 찍힘
        // 영속화 한다 (persist)
        // 저장할 때 사용한다.
        em.persist(member) // insert 날라감
        println("AFTER") // after 찍힘

        transaction.commit()

        em.close()
        emf.close()
    }

이 function을 실행시키면 BEFORE, AFTER이 차례로 print가된 뒤 persist된다.

왜?

println("BEFORE") -> 1차 캐시로 저장 -> println("AFTER") -> commit(DB로 전달)

되기 때문

여기서 중요한 것은 1차 캐시 이다.

JPA를 통해 DB에 보내기 전 메모리에 1차 캐시로 데이터를 저장하고,
그 상태에서 @Transaction 안에서 즉시 사용될 수 있다.

    fun practice2(){

        // EntityManager 생성
        val emf = Persistence.createEntityManagerFactory("hello")
        val em = emf.createEntityManager()


        //객체를 생성한 상태(비영속)
        val member = Member()
        member.id = 101L
        member.title = "회원"

        val transaction = em.transaction
        transaction.begin()

        //1차 캐시에 저장됨
        em.persist(member)

        //3번 멤버 조회
        val member1 = em.find(Member().javaClass, 101L)

        println("조회 결과 : " + member1.title)

        transaction.commit()
        em.close()
        emf.close()
    }

practice2 function를 실행하면, DB에서 불러오는 것이 아니라
1차캐시 에서 불러올 수 있다는 것을 알 수 있다.

즉, JPA는 1차 캐시에서 먼저 데이터를 찾고 없으면 DB에서 조회한다.

영속성 엔티티의 동일성 보장

    fun practice3(){

        // EntityManager 생성
        val emf = Persistence.createEntityManagerFactory("hello")
        val em = emf.createEntityManager()

        val transaction = em.transaction
        transaction.begin()

        //100번 멤버 조회
        val member1 = em.find(Member().javaClass, 100L)
        //100번 멤버 조회
        val member2 = em.find(Member().javaClass, 100L)

        println("비교 결과 : " + (member1 === member2))

        transaction.commit()
        em.close()
        emf.close()

    }

이건 어떻게 처리될까?

member1과 member2를 따로 조회하는 것이 아니라,
한 번에 조회한 뒤 비교 결과를 출력한다.

profile
야옹.

0개의 댓글