스프링 데이터 JPA 6. Update 쿼리 - KwangtaekJung/inflearn-spring-data-jpa-keesun GitHub Wiki
- find...
- count...
- delete...
- 흠.. update는 어떻게 하지?
persistence 상태의 객체의 값이 변하면 적당한 시점에 DB와 sync(flush) 되면서 update 쿼리가 나간다.
- @Modifying @Query
- 추천하진 않습니다.
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("UPDATE Post p SET p.title = ?2 WHERE p.id = ?1")
int updateTitle(Long id, String title);
- DB는 업데이트 되었어도 post 객체는 persistence context에 이전 값 그대로 남아 있고, 조회하면 DB에서 읽어 오지 않고 1차 캐시인 persistence context에서 값을 읽기 때문에 업데이트 하기 이전의 값이 나온다. 그래서 사용을 비추한다.
- 그래서 clearAutomatically 을 지원하고 있다. 명시적으로 clear 해주면 DB에서 다시 읽어오게 된다.
- 그냥 변경 감지(dirty check)를 이용하는 것이 좋다.
@Test
public void updateTitle() {
Post post = savePost();
int update = postRepository.updateTitle("Hibernate", post.getId());
Assertions.assertThat(update).isEqualTo(1);
Optional<Post> byId = postRepository.findById(post.getId());
Assertions.assertThat(byId.get().getTitle()).isEqualTo("hibernate"); // 이 테스트틑 실패한다.
}
private Post savePost() {
Post post = new Post();
post.setTitle("Spring Data JPA");
return postRepository.save(post);
}
- 업데이트 쿼리를 명시적으로 날리지 않아도 변경 감지에 의해 업데이트 되도록 하는 것이 좋다.
@Test
public void updateTitleWithDirtyCheck() {
Post post = savePost();
post.setTitle("Hibernate");
List<Post> all = postRepository.findAll();
Assertions.assertThat(all.get(0).getTitle()).isEqualTo("Hibernate");
}