해결된 질문
작성
·
546
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에서 다루는 영속화 객체의 상태 변화와 각 오퍼레이션들을 학습하는 시간을 갖길 바랍니다.