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가 적용되는 듯 함.
- JPQL은 SQL로 번역이 되어 바로 쿼리를 전송하기 때문에
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 사용