스프링 데이터 JPA 6. Update 쿼리 - KwangtaekJung/inflearn-spring-data-jpa-keesun GitHub Wiki

스프링 데이터 JPA: Update 쿼리 메소드

쿼리 생성하기

  • find...
  • count...
  • delete...
  • 흠.. update는 어떻게 하지?

    persistence 상태의 객체의 값이 변하면 적당한 시점에 DB와 sync(flush) 되면서 update 쿼리가 나간다.

Update 또는 Delete 쿼리 직접 정의하기

  • @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");
    }
⚠️ **GitHub.com Fallback** ⚠️