해당 내용은 인프런 김영한 강사님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편'의 강의를 기반으로 작성했습니다.
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
영속성 컨텍스트의 변경내용을 데이터베이스에 반영
보통 데이터베이스 트랜잭션이 딱 commit될 때 flush발생
= 영속성 컨텍스트에 쌓아둔 SQL이 데이터베이스에 날아가는 것
쉽게 이야기해서, 영속성 컨텍스트의 현재 변경 사양과 데이터베이스를 딱 맞추는 작업
플러시는 트랜잭션이 커밋되면 자동으로 발생
단, Flush가 발생했다고 트랜잭션이 commit되는 건 아님(다른 단계임)
직접 쓸 일은 거의 없지만, 알아둬야 함
em.flush();
원래는 커밋되기 전에 쿼리를 볼 수 없는데,
flush하는 순간, 쿼리가 출력이 되면서 commit전에 DB에 반영
그리고 이후 commit
혹시 flush하면 1차 캐시는 어떻게 되나요?
유지됩니다.
flush는 영속성 컨텍스트의 쓰기 지연 SQL 저장소에 있는 쿼리를 날릴 뿐
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
persist는 되었지만 commit은 되지 않았으므로 조회가 안 되지 않을까?결론적으로 말하면, 조회가 된다.
위와 같은 예제 코드처럼 JPQL 쿼리를 실행하면, 그 순간 flush를 날림
그래야 이후 문제가 없음
여태 배운 것처럼 commit되는 순간, flush가 자동으로 실행
em.setFlushMode(옵션~)
커밋이나 쿼리를 실행할 때 플러시(기본값)
커밋할 때만 플러시
= 쿼리를 실행할 땐 플러시하지 않음
위 옵션을 설정하고,
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
아래 코드를 실행하면 flush하지 않기 때문에 memberA, B, C가 조회되지 않을 것
-> 단순 해당 테이블을 조회하고 싶거나, 다른 테이블을 조회하고 싶거나 할 때 사용
다만 손대지 말고 기본값 쓰십쇼
commit 직전에 동기화지금 배워도 어려운 개념이라 이런 게 있다고 알고 넘어가자~
em.persist하면 영속상태가 됨em.find를 했는데 1차 캐시에 없고 DB에서 가져와 1차 캐시에 올림그럼 준영속은 뭐지?
영속 상태의 엔티티가 영속성 컨텍스트에서 분리하는 것
즉, 다 빼버리는 것
-> 그러면 영속성 컨텍스트가 제공하는 더티 체킹 등을 사용 못함
em.detach(entity)특정 엔티티만 준영속 상태로 전환
detach는 이 엔티티와 JPA를 분리detach를 했으므로 commit해도 insert 쿼리가 출력되지 않음직접 쓸 일이 없는데, 나중에 이해가 될 것임
em.clear()해당 영속성 컨텍스트를 초기화
똑같은 것을 조회해도, 영속성 컨텍스트가 초기화 되었으므로 select 쿼리가 두 번 나감
em.close()영속성 컨텍스트를 종료