작성
·
474
·
수정됨
0
영속성 컨텍스트가 반영 안되게 쿼리를 먼저 날려서 DB에만 반영되고 영속성 컨텍스트는 더티체킹을 못해서 반영이 안되었다고 이해했는데요
나이 업데이트 코드가 아니라 멤버를 저장 후에 바로 멤버 하나를 삭제하는 쿼리를 실하면 DB에는 멤버가 삭제되고 영속성 컨텍스트에는 반영안되어서 삭제한 멤버가 조회될 줄 알았는데 조회가 안되더라고요
deleteMemberByUsername메소드가 사용한 쿼리구요
테스트 코드 입니다.
멤버를 테스트 코드 내에서 저장하고, member5를 삭제하고 조회를 해보았습니다.
delete문을 실행하면 update와는 다르게 테이블의 구조가 변경되는 쿼리문이여서 영속성 컨텍스트에서 더티 체킹을 하는 걸까요?
답변 3
0
0
https://drive.google.com/file/d/1JdEff4WAJsEUn9sJX2VePTeGa6yo2Ry3/view?usp=sharing
MemberRepositoryTest에서 258번줄 테스트 코드와
MemberRepository 59번줄에서 delete 쿼리 메소드를 작성했습니다
보내주신 코드 잘 살펴보았습니다!
잘 작성해주셨고, 캡처해주신 그대로 테스트 코드가 되어있었습니다.
결론부터 말씀드리자면 DB 조회했을 때 데이터가 있느냐를 기준으로 처리가 달라졌다고 볼 수 있을 것 같습니다.
벌크성 수정 쿼리나 벌크성 삭제 쿼리 모두 영속성 컨텍스트에 반영하지 않고 바로 DB에 직접적으로 결과를 반영하는 것은 맞습니다.
또한 JPQL을 사용했을 시 DB로 쿼리를 날려 조회해오는 것 또한 맞습니다.
그 후에 JPQL을 통해 가져온 데이터를 처리하는 과정에서 결과 차이가 발생한 것 같습니다.
수정 쿼리: 영속성 컨텍스트에 기존 member5가 존재하고 DB 조회 결과로 조회해온 member5가 존재합니다. 영속성 컨텍스트는 @Id가 붙은 필드를 기준으로 엔티티를 관리합니다. 그리고 벌크성 수정 쿼리 특성상 영속성 컨텍스트를 거치지 않고 바로 DB에 반영했기 때문에, JPA 입장에서는 변경된 사실을 모릅니다. 기본적으로 영속성 컨텍스트에 DB 에서 조회해온 member5와 동일한 id를 가진 수정 전의 member5가 있기 때문에, JPA는 DB에서 조회해온 결과를 버리고 영속성 컨텍스트에 있는 member5를 사용합니다. 그래서 변경 내용이 반영되지 않았습니다.
삭제 쿼리: 영속성 컨텍스트에 기존 member5가 존재하고 DB 조회 결과 데이터가 존재하지 않습니다. 영속성 컨텍스트에는 member5가 존재하지만 JPQL로 DB에서 조회한 결과 해당 id를 가진 엔티티가 존재하지 않으므로 JPA는 영속성 컨텍스트의 member5도 삭제하게 됩니다. 그래서 마치 삭제시에는 더티체킹한 것처럼 해당 엔티티가 삭제된 것처럼 결과가 나오게 되었습니다.
그러면
update는 DB나 영속성 컨텍스트에서나 member5가 있다고 판단되어서, DB는 변경, 영속성은 자기가 가진 member5의 40살을 반환하고,
delete는 findByName()에서 나간 flush()로 DB에 member5가 없어지고 영속성 컨텍스트에서 member5가 남아있어서 DB와 영속성 컨텍스트에서 member5의 유무가 차이나서 영속성 컨텍스트를 수정하게 되는건가요?
아닙니다 여기선 delete 와 update 모두 그 자체는 영속성 컨텍스트에 영향을 주지 않고 바로 DB에 반영된 것이고, 그후 select jpql에서 db를 통해 가져온 결과가 있느냐에 따라 테스트 결과가 달라졌다고 이해하시는게 맞습니다!
0
안녕하세요, 인프런 AI 인턴입니다.
영속성 컨텍스트와 관련하여 삭제 쿼리가 반영되는 과정에 대해 궁금하신 것 같습니다. 이와 유사한 질문에 강사님께서 직접 답변해주신 내용이 있어 링크를 공유드립니다. 참고하시면 도움이 될 것 같습니다.
쿼리 호출 시 플러시가 자동으로 호출되어 insert 쿼리가 실행됩니다.
JPQL 실행 시 관련 있는 엔티티만 플러시하는 최적화 기능
각 링크에는 JPQL 실행 시 flush가 이루어지는 상황과 해당 쿼리와 관련 있는 엔티티에 대한 플러시 최적화에 대한 설명이 포함되어 있습니다. 질문하신 내용과 밀접하게 관련 있으니, 해당 내용을 확인해보시면 도움이 될 것입니다.
JPQL을 날리기 전에 flush를 하면 DB에는 반영이 되고 영속성에는 반영이 안돼야 하는데, Update문은 DB에만 반영되고 영속성에는 반영이 안되고, Delete문은 왜 DB에도 반영되고 영속성 컨텍스트에도 반영이 되는 건가요?