일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 스트림
- Oracle
- java 로 intellij 플러그인
- intellij 플러그인 개발
- Java
- 쿼리실행순서
- 쿼리테스트사이트
- Stream
- 로컬에서 플러그인 추가
- 오라클쿼리테스트사이트
- 플러그인 로컬 테스트
- group by group by rollup 차이
- 컬럼명중복
- plugin local
- 중복컬럼dto매핑
- dto매핑우선순위
- 포트앤어댑터 아키텍처
- 자바
- 쓰기지연저장소
- intellij 플러그인 만들기
- sql 테스트 사이트
- ls -lgaf
- hibernate 쿼리실행 순서
- Flush
- port&adapter architecture
- IntelliJ
- 쓰기지연sql저장소 쿼리실행순서
- JPA
- error 2002 (hy000): can't connect to local mysql server through socket '/tmp/mysql.sock' (2)
- Kafka
- Today
- Total
개린이 탈출기
[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에서 값을 조회해오도록 하고 싶었던 것이었다.
'에러 해결 목록' 카테고리의 다른 글
[JAVA] Gradle 구동 과정 간단 정리 (2) | 2024.11.05 |
---|---|
[JAVA] List 에 add가 왜 안돼? (feat.stream) (0) | 2024.11.04 |
[Java] stream 의 peek 과 map의 차이 (1) | 2024.09.13 |
[Oracle] (+) 유무에 따른 WHERE 절의 조건 해석 (1) | 2024.09.10 |
modify run configuration 실행 옵션 수정 (2) | 2024.07.29 |