스프링 데이터 JPA 2. JpaRepository.save() 메소드 - KwangtaekJung/inflearn-spring-data-jpa-keesun GitHub Wiki

스프링 데이터 JPA: 엔티티 저장하기

  • JpaRepository의 save()는 단순히 새 엔티티를 추가하는 메소드가 아닙니다.

    • Transient 상태의 객체라면 EntityManager.persist()
    • Detached 상태의 객체라면 EntityManager.merge()
  • Transient인지 Detached 인지 어떻게 판단 하는가?

    • 엔티티의 @Id 프로퍼티를 찾는다. 해당 프로퍼티가 null이면 Transient 상태로 판단하고 id가 null이 아니면 Detached 상태로 판단한다.
    • 엔티티가 Persistable 인터페이스를 구현하고 있다면 isNew() 메소드에 위임한다.
    • JpaRepositoryFactory를 상속받는 클래스를 만들고 getEntityInfomration()을 오버라이딩해서 자신이 원하는 판단 로직을 구현할 수도 있습니다.
  • EntityManager.persist()

  • EntityManager.merge()

@DataJpaTest
class PostRepositoryTest {

    @Autowired
    PostRepository postRepository;

    @PersistenceContext
    EntityManager entityManager;

    @Test
    public void save() {
        Post post = new Post();
        post.setTitle("jpa");
        Post savedPost = postRepository.save(post); // persist

        Assertions.assertThat(entityManager.contains(post)).isTrue();
        Assertions.assertThat(entityManager.contains(savedPost)).isTrue();
        Assertions.assertThat(savedPost == post);


        Post postUpdate = new Post();
        postUpdate.setId(post.getId());
        postUpdate.setTitle("hibernate");
        Post updatedPost = postRepository.save(postUpdate); // merge

        Assertions.assertThat(entityManager.contains(updatedPost)).isTrue();
        Assertions.assertThat(entityManager.contains(postUpdate)).isFalse();
        Assertions.assertThat(updatedPost == postUpdate);

        List<Post> all = postRepository.findAll();
        Assertions.assertThat(all.size()).isEqualTo(1);
    }
}

merge 되는 경우에는 파라미터로 넘긴 postUpdate는 영속성 관리에 있지 않으므로 변화 감지를 하지 않는다. 안정하게 하려면 리턴 받은 값을 사용한다. 리턴 받은 값은 perisist던 merge던 영속성 관리를 받는다.

⚠️ **GitHub.com Fallback** ⚠️