Spring Data JPA 관련 질문드립니다.

20.04.09 14:27 작성 조회수 39

0

삭제된 글입니다

답변 2

·

답변을 작성해보세요.

0

답변 감사합니다 영한님!!

이해가 안가서 한참을 헤매고 있었는데, 영한님의 답변으로 명쾌하게 이해가 되었습니다.

두 가지 질문 모두 강의 내용을 잘 떠올리면 찾을 수 있는 질문이었는데,,, 생각이 짧았습니다.

책을 통해 추가적인 학습을 하도록 하겠습니다.

감사드립니다!

0

안녕하세요. Dongmin Choi님

flushAutomatically는 JPQL 실행전에 flush가 호출되므로 일반적인 상황에서는 사용할 필요는 없습니다.

그런데 JPA 플러시 옵션중에 JPQL을 실행해도 flush가 호출되지 않도록 강제하는 옵션이 있습니다. 이 옵션을 사용하는 특별한 경우에 필요한 것으로 생각됩니다. (저도 이 옵션을 실무에서 사용하지는 않아서, 이럴 때 필요할 것 같다고 추측해봅니다. 플러시 옵션에 대한 내용은 기본편 강의를 참고해주세요)

그 다음 질문은 조금은 어려운 내용입니다^^!

Q: 그리고 추가적으로 벌크 연산 후 (clearAutomatically = false 상태로) findById 를 하면 영속성 컨텍스트에 엔티티가 존재해 쿼리를 날리지 않지만, findAll 을 한 경우 쿼리를 날리는데 벌크 연산이 진행되지 않는 값을 날립니다.

이런 경우는 DB에 접근을 했는데 조회한 값이 영속성 컨텍스트를 업데이트 시키는 것이 맞지 않나요???

A: 여기에 JPA의 마법이 있습니다. 기본편 강의를 잘 떠올려 보시면, 영속성 컨텍스트는 항상 동일성 보장을 해준다고 했습니다. 그런데 벌크 연산은 영속성 컨텍스트를 무시하고 DB의 값을 변경하는 것이기 때문에 영속성 컨텍스트의 엔티티를 변경하면 안됩니다. 이후에 findAll을 해서 JPQL 쿼리가 실행되더라도 영속성 컨텍스트의 값은 변경되면 안됩니다. 그렇게 되면 영속성 컨텍스트의 동일성 보장이 깨집니다!

예를 들어서 

EntityA a1 = em.find("idA")

em.update(벌크연산)

EntityA a2 = em.JPQL 실행, findAll() 등등...

이렇게 되었어도, 영속성 컨텍스트는 동일성을 보장하기 때문에 a1 == a2 여야 하는 것이지요. (중간에 영속성 컨텍스트를 초기화 하지 않았다고 가정하면요)

이 동일성 보장을 위해서 JPA는 쿼리가 실행되어도 그 결과값에서 같은 식별자를 가진 엔티티가 영속성 컨텍스트에 있으면, 쿼리 결과로 만들어진 엔티티를 버리고, 기존에 영속성 컨텍스트에 있던 엔티티를 남겨둡니다.

관련해서 더 상세한 내용이 궁금하시면 JPA책 10.6.2 영속성 컨텍스트와 JPQL 부분을 참고해주세요^^

감사합니다.