[JPA] flush 와 clear 의 차이
jpa 와 jdbcTemplate 을 함께 사용 중인데, Jpa로 엔티티를 조회해온 뒤, jdbcTemplate 으로 데이터를 수정하고 해당 값을 다시 조회하여 사용하는 과정에서 반영된 값을 db에서 다시 조회해와야만 하는 케이스가 발생했다.
예를 들어 jpa로 조회해온 A 테이블의 a1 엔티티를 수정하는데, A 테이블의 전체 개수(max 값) 를 A테이블의 serial_Number 컬럼에 저장해주어야 한다.
이때, 전체 개수를 조회해오는 로직을 자바로 풀지 않고, 서브쿼리로 넣어 사용했다.
이러한 경우 다음과 같은 문제가 발생할 수 있다.
1. jpa 를 통해 a1 를 조회하면 a1은 영속성 컨텍스트에서 관리 됨
2. 이때, 조회해 온 'a1`의 `serial_Number` 의 컬럼 값을 수정하여 update 하는데, 그 방식이 jdbcTemplate을 이용하는 방식임.
⇒ db에 수정된 a1은 저장됨 / 영속성 컨텍스트 a1의 새로운 serial_Number 에 대해 아무 것도 모름
3. 이후 로직을 위해 db에 반영된 데이터를 가져와야함.
- 이때, clear() 없이 find 할 시, 동일한 키 값의 엔티티가 영속성 컨택스트(아마두 1차캐시)에 남아있으므로, db에서 조회하지 않고 영속성 컨텍스트에 존재하는 엔티티를 가져오게 됨( = 수정된 `serial_Number' 가 반영되지 않은 버전)
4. 따라서 이후 로직 동작 시 문제가 발생할 수 있음
flush() 대신 clear() 를 사용해야하는 이유
clear()는 영속성 컨텍스트를 비우는 동작을하고,
flush() 는 영속성 컨택스트는 비우지 않고 오직 쓰기지연 저장소에 있는 쿼리를 db에 반영하는 동작을 한다.
나의 문제는 영속성 컨택스트에 기존 키 값으로 이전 버전의 엔티티가 존재하므로,
엔티티 매니저가 db에서 수정된 데이터를 조회해오지 않는다는 것이었이었으므로 clear()를 선택했다.
따라서 강제로 영속성 컨텍스트를 비워주어 엔티티 매니저가 db에서 값을 조회해오도록 하고 싶었던 것이었다.