개린이 탈출기

[JPA] flush 와 clear 의 차이 본문

에러 해결 목록

[JPA] flush 와 clear 의 차이

yooverd 2024. 9. 26. 13:07
728x90
반응형
SMALL

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에서 값을 조회해오도록 하고 싶었던 것이었다.

728x90
반응형
LIST