merge() 메소드에 넘긴 그 엔티티의 복사본을 만들고, 그 복사본을 다시 Persistent 상태로 변경하고 그 복사본을 반환하는 방식이며, 데이터베이스에 sync를 하므로 Entity의 상태변화를 데이터베이스에 Update 시킵니다. 만약 ID가 데이터베이스에 해당하는게 없으면 새로운 데이터를 Insert 합니다.
Detached 상태의 객체 : 한 번이라도 데이터베이스에 Persistent 상태가 됐던 객체입니다. 이 객체에 맵핑이 되는 레코드가 테이블에 있는 경우 즉, 이 객체는 ID가 있음 ID에 맵핑이 되는 테이블 데이터가 있을 수도 있고, 없으면 새로 추가됩니다.
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
@Test publicvoidcrud(){ Post post = new Post(); post.setId(1L); post.setTitle("jpa"); postRepository.save(post);/* persist */
Post postUpdate = new Post(); postUpdate.setId(1L); postUpdate.setTitle("hibernate"); postRepository.save(postUpdate);/* merge */
List<Post> all = postRepository.findAll(); assertThat(all.size()).isEqualTo(1); }
post 객체는 transient 상태이므로 insert가 발생하게 되고, postUpdate 객체는 detached 상태이므로 update가 발생하게 됩니다.
Post postUpdate = new Post(); postUpdate.setId(post.getId()); postUpdate.setTitle("hibernate"); Post updatedPost = postRepository.save(postUpdate);/* merge */
List<Post> all = postRepository.findAll(); assertThat(all.size()).isEqualTo(1); }
post를 캐싱하고 있으며와 savedPost의 인스턴스를 가지고 있어서 같으며, updatedPost는 캐싱하고 있고 postUpdate는 캐싱하고 있지 않으므로 두 인스턴스는 다릅니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@Test publicvoidcrud(){ Post post = new Post(); post.setTitle("jpa"); Post savedPost = postRepository.save(post);/* persist */
Post postUpdate = new Post(); postUpdate.setId(post.getId()); postUpdate.setTitle("hibernate"); Post updatedPost = postRepository.save(postUpdate);/* merge */