JPA merge

portal2moon·2020년 11월 9일
0

JPA

목록 보기
1/1

merge

준영속 상태의 엔티티를 영속상태로 변경해주는 메서드이다.

story


member라는 entity가 존재한다고 가정.
영속성 컨텍스트에 영속화를 하고 트렌젝션을 커밋하여 db에 push 후 영속성 컨텍스트를 close (persist -> commit -> close).

이제 member 는 close 로 인해 준영속 상태가 되었다.
준영속 상태의 entity는 값을 변경해도 관리 되지 않기 때문에 db에 아무런 영향을 주지 못한다.

member.setUsername("kale") 이라고 변경.

그 후 새로운 트렌젝션을 열어서 Member mergeMember = entityManager.merge(member);

어떤일이 벌어질까?

outcome


db에 존재했던 member 의 이름이 kale 로 바뀐다.

merge의 동작방식은 다음과 같다.

  1. 인자로 넘어온 entity의 id를 기반으로 entity를 찾는다.
    1차 캐시를 먼저 찾고 없다면 db를 조회한다.
  2. 찾은 entity를 영속화 하고 merge로 넘어온 entity의 정보를 찾은 entity에 밀어 넣는다.
    mergeMember가 영속상태로 변경되고 이름이 kale인 member entity로 값이 채워진다.
  3. 영속상태 이므로 트렌젝션 커밋 시 변경을 감지하여 db에 update 한다.

처음에는 merge가 준영속상태의 entity를 다시 영속상태로 변경한다고 했지만 사실 인자로 넘겨온 값을 기반으로 새로운 entity(mergeMember)를 영속화 하는 것이다.

결론


원래 존재 했던 준영속상태 entity인 member는 계속 준영속 상태로 남아있다. 사용될 필요가 없으므로 준영속 entity를 참조하던 변수를 영속 entity를 참조하도록 변경하는것이 안전하다.

member = entityManager.merge(member)

병합은 준영속, 비영속을 신경쓰지 않는다.

따라서 다음과 같은 코드도 가능하다.

Member member = new Member();
Member newMember = em.merge(member);
tx.commit();

member는 비영속 상태의 entity 이며 db에서 조회해도 없는 값이기에 새로운 엔티티를 생성해서 병합한다. merge는 식별자 값으로 entity를 조회할 수 있으면 불러서 병합, 조회 불가능 하면 새로 생성해서 병합하기 때문에 save or update 의 기능을 수행한다.


저자 김영한의 자바 orm 표준 jpa 프로그래밍을 참고하여 작성하였습니다. (강추)

profile
아예 안쓰는것보단.. 조금이라도 써 놓는 것이 도움이 될것같아 만든 벨로그입니다

0개의 댓글