목표 

pk로 엔티티를 조회 해온다. 

조회한 엔티티를 복제한다. 일부 내용만 바꾸고 새로운 pk를 가진 엔티티로써 저장한다. 

즉, 4번 pk 엔티티를 조회하여 복제한다. (4번 엔티티의 내용은 변경하지 않는다. )

일부 내용만 바꾼 후, 5번 엔티티로써 저장한다. 

찾아본 내용 

"jpa entity copy"로 구글링 했는데 stackoverflow의 How to clone a JPA entity 글이 있었다.

 "EntityManager.detach() 를 쓰세요." 

 

entityManager.detach()

엔티티 매니저가 관리하는 영속성 컨텍스트에서 분리된 상태가 된다. 

즉, 더티 체킹(변경 감지)의 대상에서 제외되는 것이다. 

준영속 상태로 만든 다음 데이터를 세팅하고, 다시 엔티티 매니저의 관리대상이 되도록 persist() 하라는 답변이었다. 

 

Member엔티티의 PK를 FK로 사용하는 엔티티의 정보까지 바뀌도록 신경써야 해서 삽질이 길었다. 

Member엔티티를 persist() 하기 전에,  FK로 연관된 엔티티들을 일일이 set해줬다. 

Member 엔티티와 연관관계에 있는 엔티티들은 전부 Cascade.Type All로 설계했기 때문에 다 연결되어 있었기 때문이다. 

 

수정한 예시 코드다. 

아래와 같은 흐름으로 수정하여 해결할 수 있었다. 

Long targetId = 1L;

Member oldMember = em.find(Member.class, targetId);
Hobby oldHobby = oldMember.getHobby();

em.detach(oldMember); // 준영속 상태로 만든다. (JPA가 관리하지 않는 객체가 된다)
oldMember.setName("minzy");
oldMember.setId(targetId + 1L); // PK를 1증가시킨다 

oldMember.setHobby(oldHobby); // 연관관계에 있는 엔티티 정보도 set해야 한다. 

em.persist(oldMember); // 영속성 컨텍스트의 1차 캐시에 올라가도록, 영속 상태로 만든다.

참고한 글 

JPA구동 방식

영속성 컨텍스트와 플러시 이해하기

 

[JPA] 영속성 컨텍스트와 플러시 이해하기

영속성 컨텍스트 JPA를 공부할 때 가장 중요한게 객체와 관계형 데이터베이스를 매핑하는 것(Object Relational Mapping) 과 영속성 컨텍스트를 이해하는 것 이다. 두가지 개념은 꼭 알고 JPA를 활용하자.

ict-nroo.tistory.com

 

728x90

+ Recent posts