본문 바로가기
JPA

JPA 동작 확인

by 문자메일 2022. 4. 6.

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

 

 

 

 

 

 

public class JpaMain {
    public static void main(String[] args){

        // EntityManagerFactory는 애플리케이션 로딩 시점에 딱 하나만 만들어놔야 한다.
        // = 하나만 생성해서 애플리케이션 전체에서 공유해서 사용한다.
       EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

       // DB 커넥션을 얻어서 쿼리를 날리고 종료되는 그런 일관적인 단위를 수행할때 마다 EntityManager 를 꼭 만들어 주어야 한다.
        // 엔티티 매니저는 쓰레드간에 공유 X ( 매번 요청시마다 새로 생성하고, 쓰고 나면 바로 버려야 한다.)
        EntityManager em = emf.createEntityManager();

        // 아래 같은 일련의 과정이 정석적인 코드이다, 다만 실 사용시 annotation을 붙이면 스프링이 알아서 다 해준다.
        // JPA의 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다.
        EntityTransaction tx = em.getTransaction();

        tx.begin();
        try{
            //생성
            Member member = new Member();

            member.setId(4L);
            member.setName("helloB");

            em.persist(member);

            // 조회
            Member findMember = em.find(Member.class,1L);
            
            //수정
            // jpa를 통해서 Entity를 가져오면 JPA가 관리를 하고, 변경유무를 트랜잭션 커밋하는 과정에서 다 체크를 한다.
            // 변경사항 있으면 트랜잭션 커밋 직전 업데이트 쿼리 만들어서 날리고 트랜잭션 커밋한다.
            findMember.setName("hellojpa");

            tx.commit();
        } catch (Exception e){
            tx.rollback();
        } finally {
            // entity manager가 내부적으로 데이터베이스 커넥션을 물고 동작하기 때문에 사용을 다 하고 나면 꼭 닫아줘야 한다.
            em.close();
        }

        em.close();

        emf.close();
    }
}

 

 

 

 

JP에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑 (Object Relational Mapping)
  • 영속성 컨텍스트

 

영속성 컨텍스트

  • JPA를 이해하는데 가장 중요한 용어
  • "엔티티를 영구 저장하는 환경" 이라는 뜻
  • EntityManager.persist(entity);
    • 위 명령의 뜻은 DB에 저장한다는 것이 아니라 영속성 컨텍스트를 통해서 Entity를 영속화 한다는 뜻이다.
      더 자세히 말하면 DB에 저장하는 것이 아니라 Entity를 영속성 컨텍스트에 저장한다는 의미
    • EntityManager를 통하여 영속성 컨텍스트에 접근

 

 

엔티티의 생명주기

  • 비영속 (new)
    • 영속성 컨텍스트와 관계가 없는 새로운 상태
  • 영속 (managed)
    • 영속성 컨텍스트에 관리되는 상태 (Entity가 1차 캐시에 올라가 있는 상태)
  • 준영속(detached)
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제 (removed)
    • 삭제된 상태

 

 

 

 

  • 1차 캐시에서 조회





  • 영속 엔티티의 동일성 보장
Member member1 = em.find(Member.class, 4L);
Member member2 = em.find(Member.class, 4L);
System.out.println(member1 == member2); //true

1차 캐시가 있기에, 활용하여 반복 가능한 읽기(REPEATALBE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 활용 가능하다.

 

 

  • 엔티티 등록 / 트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();

// 아래 같은 일련의 과정이 정석적인 코드이다, 다만 실 사용시 annotation을 붙이면 스프링이 알아서 다 해준다.
// JPA의 모든 데이터 변경은 트랜잭션 안에서 실행해야 한다.
EntityTransaction tx = em.getTransaction();

tx.begin();
try{
    //생성
    Member member1 = em.find(Member.class, 4L);
    Member member2 = em.find(Member.class, 4L);

    em.persist(member1);
    em.persist(member2);
    // 여기까지는 INSERT SQL을 데이터베이스에 보내지 않는다.


    // 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
    tx.commit();

트랜잭션을 commit() 하는 시점에 쓰기 지연 SQL 저장소에 있던 것들이 flush()가 되면서 insert sql들이 실행되고, 해당 트랜잭션이 commit 된다.

 

 

  • 변경 감지(Dirty Checking)

 

 

  • 엔티티 삭제

 

 

플러시

영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것

 

 

플러시가 발생하면

1. 변경 감지 수행

2. 수정된 엔티티 쓰기 지연 SQL 저장소에 등록

3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 (등록, 수정, 삭제 쿼리)

 

 

영속성 컨텍스트를 flush 하는 방법

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

 

플러시는

영속성 컨텍스트를 비우는 것이 아니다

영속성 컨텍스트의 변경내용을 데이터베이스에 동기화

트랜잭션이라는 작업 단위가 중요하다. -> 커밋 직전에만 동기화 하면 된다.

 

 

 

준영속 상태

  • 영속 -> 준영속 (entity가 1차 캐시에 올라가 있는 상태가 영속 상태이다.)
  • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

 

'JPA' 카테고리의 다른 글

스프링 데이터 JPA 페이징과 정렬  (0) 2022.05.06
순수 JPA 페이징과 정렬  (0) 2022.05.06
JPA 모델링 설계하는 순서  (0) 2022.04.09
엔티티 매핑  (0) 2022.04.09
JPA에서 CRUD  (0) 2022.04.06

댓글