[Exception] [JPA]HibernateException: identifier of an instance of com.mappingtest.Locker was altered from 1 to 2

NtoZ·2023년 8월 29일
1

MainProject

목록 보기
2/2
post-thumbnail

발단

  • 프로젝트를 진행하던 중, 궁금증이 생겼다. OneToOne 매핑관계에서 연관된 테이블 정보를 바꾸기 위해 setter를 사용한다면 손쉽게 수정 api를 구현할 수 있지 않을까?

    결론부터 말하자면, 연관관계 매핑이 된 상태에서 식별자만을 단순 setter로 변경할 수 없다.
    정확히 말하자면, setter로 변경하는 것은 단순히 Long 타입 id가 아니라 그 정보를 매핑하고 있는 객체 자체가 되어야 한다.
    그렇지 않으면 다음같은 에러를 확인하게 된다.
[Exception] [JPA]HibernateException: identifier of an instance of com.mappingtest.Locker was altered from 1 to 2

의문점과 해결과정

  • 다음 그림에서 보듯, PLANT_OBJ 엔티티와 LEAF 엔티티의 매핑 관계는 OneToOne이다.

  • PLANT_OBJ의 leafId를 수정하고자 할 때, 단순히 클라이언트에서 받은 leafId를 setter로 매핑한다면 손쉽게 PLANT_OBJ 객체에 존재하는 LEAF 정보만 수정할 수 있지 않을까?라는 궁금증이 생겼다.

    그러나 실천에 옮긴 순간다음과 같은 예외가 발생했다.

  "org.springframework.orm.jpa.JpaSystemException: identifier of an instance of com.mappingtest.Locker was altered from 1 to 2; nested exception is org.hibernate.HibernateException: identifier of an instance of com.mappingtest.Locker was altered from 1 to 2"

  • HibernateException: identifier of an instance of com.mappingtest.Locker was altered from 1 to 2
    • 이 예외는 예외는 JPA 엔티티의 식별자 값을 변경하려고 할 때 발생한다. JPA에서 관리되는 엔티티의 식별자 값은 영속성 컨텍스트 내에서 변경되면 안 된다. 엔티티 식별자를 변경하려면 새로운 엔티티를 생성하거나, 기존 엔티티를 삭제하고 새로운 엔티티를 추가해야 하는 것이다.

  • 추가: GPT 답변

결론

  • 영속성 컨텍스트에 대한 이해가 부족해서 발생한 일이었다.
    JPA에서 특정 테이블이 다른 테이블의 식별자를 보유하고 있을 때 setter로 id만 바꿔줄 수는 없다. 무조건 객체까지 변경이 필요하다.
profile
9에서 0으로, 백엔드 개발블로그

0개의 댓글