해결됨
자바 ORM 표준 JPA 프로그래밍 - 기본편
em.flush 발생 시점에 대한 부가적인 질문
오랜만에 관련된 업무 진행하다가 발생한 궁금점에 대하여 질문드리게 되었습니다. 우선 한 트랜젝션의 영속성 컨텍스트에 대하여 쓰기 지연 저장소에 쌓인 쿼리가 flush() 되는 경우는 다음 세 가지로 이해하였습니다. flush() 직접호출트랜젝션 commit()JPQL 직접 발생시, 해당 JPQL 발생 이전 다음과 같은 연관관계가 가정되어 있다고 해보겠습니다. public class Car{
@Id
private Long id;
}
public class Wheel {
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "car_id")
private Car car;
} Wheel 이 연관관계의 주인이며, Car 와 M:1 관계로 매핑되어 있습니다. 이 때, 다음과 같은 로직을 수행해보겠습니다. (1L 의 Wheel 이 2L 의 Car 에 매핑되어 있음) Wheel wheel = em.find(Wheel.class, 1L);
wheel.setCar(null); // 1)
em.createQuery("delete from Car c where c.id = :id")
.setParameter("id", 2L)
.exeucteUpdate(); // 2) 이와 같이 수행되었을 때, 1번 시점에서 영속성 컨텍스트에 보관중인 Wheel 의 Car 값이 변경되어 Update 쿼리가 발생하여 쓰기 지연 저장소에 저장되었을 것으로 추측합니다. 2번 시점은 위에서 말한 'flush 발생시점' 중 3번에 해당한다고 생각했습니다 (JPQL 직접 수행). 그렇다면 쓰기 지연 저장소에 쌓인 Update 쿼리가 나간 이후, 직접 수행하려는 Delete JPQL 을 발생시켜서 아무 문제 없이 수행되어야 하는거 아닌가 싶었는데, 위 로직은 FK 제약조건에 위배되어 수행되지 못합니다. 1번과 2번 사이에 강제로 em.flush() 를 진행해주면, 그제서야 update 쿼리가 발생한 뒤에 delte 쿼리가 발생하여 위 로직이 아무 에러 없이 수정되는 모습을 확인했습니다. 왜 이 상황에서는 flush 가 자동으로 발생하지 않나요? 열심히 찾아봤을 때... JPA 측에서 제공하는 3번 (JPQL 발생시 flush 됨) 에 대한 명확한 [기준] 은 제시하고 있지 않은 것으로 보이는데 맞을까요??