ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA에서 신규 엔티티 처리: EntityManager.persist()와 JpaRepository.save()의 차이점 파악하기
    JPA 2024. 4. 30. 22:08

    동일한 신규 Entity를 생성하여 EntityManager.persist()JpaRepository.save()를 통해 영속화 시켰을 때의 동작과 결과가 다를 때가 있다. 이에 대해 알아보자.

    EntityManager.persist()

    persist()를 호출할 때 전달된 엔티티 인스턴스 자체가 영속 상태가 되어 변화를 추적한다. 이 메소드는 반환값이 없으며, 저장하는 객체와 영속성 컨텍스트에 들어간 객체가 동일한 참조를 유지한다.

    JpaRepository.save()

    save() 메소드는 내부적으로 EntityManagerpersist() 또는 merge()를 호출할 수 있다. 이 메소드의 행동은 전달된 엔티티의 상태에 따라 달라진다.

    • 신규 엔티티일 경우: 일반적으로 persist()가 호출되어 엔티티가 영속 상태가 된다.
    • 이미 존재하는 엔티티일 경우: merge()가 호출된다. merge()는 기존 엔티티의 상태를 새 엔티티의 상태로 복사하고, 그 결과로 새로운 엔티 객체를 반환한다. 이 경우, 저장하고자 했던 객체와 반환된 객체가 다른 참조를 가질 수 있다.

    차이 발생 이유

    신규 엔티티를 판단하는 기준이 중요하다. 일반적으로 JPA는 엔티티의 ID가 null이거나 0인 경우를 신규 엔티티로 간주한다. 그러나 ID의 생성 전략이 @GeneratedValue가 아니고, 로직에서 ID 값을 직접 설정하는 경우가 있다면, 이는 JpaRepository에서 신규 엔티티로 인식되지 않을 수 있다. 이 경우, JpaRepository.save()는 엔티티가 이미 존재한다고 판단하고 merge()를 호출할 가능성이 있다. 따라서, merge()를 사용하면 원본 엔티티와 반환된 엔티티가 다른 참조를 가질 수 있다.

    결론

    따라서, 같은 데이터를 저장하더라도 EntityManager.persist()는 원본 객체를 그대로 영속화하여 참조가 유지되는 반면, JpaRepository.save()는 상황에 따라 merge()를 사용하여 새 객체를 반환할 수 있어, 원본 객체와 다른 참조를 가진 객체가 반환될 수 있다. 이러한 차이를 이해하는 것은 JPA 및 Spring Data JPA를 사용하여 데이터를 효율적으로 관리하기 위해 매우 중요하다.

Designed by Tistory.