설치&설정 관련/Spring Framework

JPA 에서 FLUSH 처리시 실행 순서

lahuman 2024. 8. 30. 18:26
728x90

Hibernate는 연관된 엔터티 상태 작업의 순서대로 SQL 문을 실행하지 않습니다.

다음과 같은 코드가 있다고 예상할 경우

Person person = entityManager.find(Person.class, 1L);
entityManager.remove(person);

Person newPerson = new Person();
newPerson.setId(2L);
newPerson.setName("John Doe");
entityManager.persist(newPerson);

저희는 DELETE 질의 이후 INSERT 질의를 기대 합니다.

하지만 동작은 아래와 같습니다.

INSERT INTO Person (name, id)
VALUES ('John Doe', 2L)

DELETE FROM Person WHERE id = 1

SQL 문이 실행되는 순서는 엔티티의 상태 변화가 아닌, ActionQueue에 의해서 지정됩니다.

ActionQueue에서는 다음 순서로 모든 작업을 실행합니다 .

  1. OrphanRemovalAction
  2. EntityInsertAction또는EntityIdentityInsertAction
  3. EntityUpdateAction
  4. QueuedOperationCollectionAction
  5. CollectionRemoveAction
  6. CollectionUpdateAction
  7. CollectionRecreateAction
  8. EntityDeleteAction

만약, 꼭 삭제를 먼저 실행하고 싶다면 다음과 같이 강제로 flush를 호출 해야 합니다.

Person person = entityManager.find(Person.class, 1L);
entityManager.remove(person);
entityManager.flush(); // 강제 flush로 SQL 실행 

Person newPerson = new Person();
newPerson.setId(2L);
newPerson.setName("John Doe");
entityManager.persist(newPerson);

마치며

이 부분을 잘 이해 못해서 삽질을 오래 하였습니다.

강제로 flush 하기 보다 OrphanRemovalAction 를 활용하여 처리 하는게 좋게 보여지기도 합니다.

참고 자료

728x90