인프런 커뮤니티 질문&답변

blossom_mind님의 프로필 이미지

작성한 질문수

스프링 데이터 JPA

JPA 프로그래밍 5. 엔티티 상태와 Cascade

영속성 공부하다가 궁금한게 생겼습니다 .

해결된 질문

작성

·

547

0

class A 

{

  @GeneratedValue

  @Id

  private Long id; 

}

일떄 아래 run 메서드에서 

@Transactional

@Component

public class JpaRunnerManyToMany implements ApplicationRunner {

@PersistenceContext

EntityManager entityManager;

@Override

public void run(ApplicationArguments args) throws Exception {

A a1 = new A1();

a1.setId(1l); <== 해당 부분 에러가 뜨는데요
a1.setUsername("test");

entityManager.persist(1L);

이경우 detached entity passed to persist 에러가 생기는데요

제가 강의를 들을떄 persist()를 할떄 비로소 1차캐쉬에 들어가서 jpa가 관리중인 상태가 된다고 들었는데 그렇다면 
persist()하기 전에 1L을 id로 셋팅을 하고 persist()와 동시에  영속성상태로 올라갔을떄 @GeneratedValue 라는 어노테이션이 주키의 자동생성을 위한것이라고 들었는데 그렇다면 1L로 persist 메소드를 적용했을떄 1l이 이미 있으면 @GeneratedValue가 적용이 안되서 에러가 발생하는것일까요. 

해석하면 detached entity passed to persist

detach가 persist상태로 넘겨졌다라는걸로 해석되는데 

만약에 A a = new A();
a.setId(1L);  로 entityManager.persist(a); 실행하면 정확히 어떤흐름으로 가는지 궁금합니다 .

답변 1

2

백기선님의 프로필 이미지
백기선
지식공유자

@GeneratedValue가 적용이 안되서라기 보다는 문맥적으로 id를 자동생성하겠다고 선언하셨는데 id를 직접 정해놓고 persist를 호출하면 JPA는 해당 객체가 detached 상태의 객체라고 생각합니다. detached 객체는 이미 이전에 한번 영속화 되었던 적이 있는 객체, 즉 이 경우에는 id를 가지고 있는 객체면 그렇게 생각합니다. detached 객체를 다시 영속화 하려면 persist가 아니라 merge를 사용해야 합니다.

JPA에 대한 학습을 하셔야 합니다. JPA에서 다루는 영속화 객체의 상태 변화와 각 오퍼레이션들을 학습하는 시간을 갖길 바랍니다.