JPA

[JPA] 5. 영속성 컨텍스트 - 2

inuma 2020. 12. 31. 01:45
프로젝트 git url github.com/rtef23/JpaStudy
필요 1. docker
2. docker-compose
프로젝트 정보 mysql : 5.7 - docker image
java : 1.8

 

Flush

정의

  • 영속성 컨텍스트의 변경 사항을 DB에 반영하는 작업

동작 방식

  • 변경 감지
  • 변경 감지된 엔티티를 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송(Insert, Update, Delete)

특징

  • 영속성 컨텍스트의 내용을 비우지 않는다.

flush하는 방법

  • entityManager.flush() api 사용
  • 트랜잭션 커밋
  • JPQL 쿼리 실행
    • JPQL은 SQL로 번역이 되어 바로 쿼리를 전송하기 때문에
      아직 DB에 반영되지 않는 영속되어 있는 엔티티에 대해서
      JPQL의 결과 집합에 포함이 되지 않을 수 있기 때문에 자동 flush가 적용되는 듯 함.
Member testMember1 = new Member(5L, "test-name5");
Member testMember2 = new Member(6L, "test-name6");
Member testMember3 = new Member(7L, "test-name7");

entityManager.persist(testMember1);
entityManager.persist(testMember2);
entityManager.persist(testMember3);

Query query = entityManager.createQuery("select m from Member m", Member.class);
List<Member> members = query.getResultList();
//createQuery api를 사용한 시점이 아닌 getResultList를 사용한 시점에서 쿼리가 전송된다.

entityTransaction.commit();

 

준영속 상태

정의

  • 영속 상태의 엔티티가 영속성 컨텍스트에 의해 관리되지 않는 상태(detached)

엔티티를 준영속 상태로 만드는 방법

  • detach api 사용
Member testMember1 = entityManager.find(Member.class, 1L);
testMember1.setName("SSSSSS");

entityManager.detach(testMember1);
//식별자가 1L인 엔티티를 준영속 상태로 만들어 update 쿼리가 전송되지 않게 된다.

entityTransaction.commit();
Member testMember1 = entityManager.find(Member.class, 4L);
testMember1.setName("SSSSSS");

entityManager.detach(testMember1);

Member testMember2 = entityManager.find(Member.class, 4L);
testMember2.setName("SSSS");

//testMember1과 testMember2는 동일한 식별자의 엔티티이지만
//식별자가 4L인 엔티티에 대해서 select 쿼리도 2번 전송이 되었고
//testMember2의 수정 사항만 update 쿼리가 전송되었다.
entityTransaction.commit();
  • clear api 사용