객체지향 쿼리 심화
1. 벌크 연산
- 기존에 entity 수정은 영속성 컨텍스트에 의한 더티 체킹이다. 병합을 사용하고, 삭제는 remove를 이용했다.
- 많은 수의 연산을 영속성 컨텍스트를 통해서 사용하면 시간이 오래 걸린다.
- 벌크 연산을 통해서 이 갈증을 해소할 수 있는데 문제는 영속성 컨텍스트를 무시하고 DB에 직접 질의한다.
-
따라서 DB의 값, 영속성 컨텍스트에 올라간 값이 달라질 수 있다.
- em.refresh()사용
- 벌크 연산을 먼저 사용하고 영속화
- 벌크 연산을 사용하고 영속성 컨텍스트 초기화
2. JPQL과 영속성 컨텍스트
- JPQL로 엔티티를 조회하면 영속성 컨텍스트에서 관리되지만 엔티티가 아니라면 영속성 컨텍스트에서 관리되지 않는다.
- 만약 영속성 컨텍스트에 관리되는 엔티티를 JPQL로 조회하면 JPQL로 데이터베이스에서 조회한 결과를 버리고 대신에 영속성 컨테스트에 있던 엔티티를 반환한다.
- 이는 영속성 컨텍스트가 영속 상태인 엔티티의 동일성을 보장하기 위해서다.
- em.find(엔티티 매니저 이용)는 영속성 컨텍스트를 먼저 들러서 확인한다.
- JPQL은 항상 DB에서 조회하고 본다.
3. JPQL과 플러시 모드
- 플러시 모드는 영속성 컨텍스트의 변경 내역을 DB에 동기화하는 것이다.
- JPA는 플러시가 일어날 때 영속성 컨텍스트에 등록, 수정, 삭제한 엔티티를 찾아서 SQL로 만들어 DB에 반영한다.
em.flush()를 직접 사용해도 되지만 보통 FlushMode로 커밋, 쿼리 실행 직전에 호출된다.- FlushModeType.AUTO: 커밋 또는 쿼리 실행 시 플러시 (default)
- FlushModeType.COMMIT: 커밋 시에만 플러시
- JPQL은 영속성 컨텍스트를 고려하지 않는다. 따라서 JPQL 전 영속성 컨텍스트 내용을 DB에 반영해야 한다.
- commit으로 두면 JPQL이 조회한 값과(old) 영속성 컨텍스트로 업데이트 한 값(new) 간 불일치가 있을 수 있다.