목표
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차 캐시에 올라가도록, 영속 상태로 만든다.
참고한 글
728x90
'일상 > Today I Learn(TIL)' 카테고리의 다른 글
외래키 제약 때문에 테이블 삭제 안된 문제 (0) | 2021.11.11 |
---|---|
JPA 컬럼에 제약조건 @ColumnDefault와 @DynamicInsert (0) | 2021.11.11 |
Mac 에서 Python 버전 변경 (1) | 2021.11.10 |
객체지향 설계 5원칙 - SOLID (0) | 2021.11.10 |
아파치 서비스 시작 안되고 Permission error 에러 (0) | 2021.11.09 |