Spring Data JPA에서 새로운 Entity인지 판단하는 방법

Kkd·2024년 11월 21일
0

매일메일 개념정리

목록 보기
4/93

Spring Data JPA에서 새로운 Entity인지 판단하는 것이 중요한 이유

Spring Data JPA에서 엔티티가 새로운 엔티티인지 판단하는 방법은 식별자(ID)의 값을 기준으로 이루어집니다.
기본적으로 JPA는 엔티티가 새로운 상태인지 또는 이미 존재하는 상태인지를 다음과 같은 조건을 통해 판단합니다.


1. 식별자(ID)가 null인지 확인

JPA에서는 식별자(ID) 필드가 null이면 해당 엔티티를 새로운 엔티티로 간주합니다.
즉, @Id로 지정된 필드에 값이 없으면 JPA는 아직 이 엔티티가 데이터베이스에 저장되지 않았다고 판단합니다.

예시 코드

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}
  • ID가 null인 경우:
    User user = new User();
    user.setName("Alice");
    // id가 null이므로 새로운 엔티티로 간주됨
  • ID에 값이 있는 경우:
    User user = new User();
    user.setId(1L); // id가 null이 아니므로 기존 엔티티로 간주됨
    user.setName("Bob");

2. EntityManagerpersist() 동작 원리

EntityManagerpersist() 메서드는 엔티티가 새로운 상태일 때만 동작합니다.
새로운 엔티티로 간주되면 영속성 컨텍스트에 등록되고, 이후 flush() 시점에 데이터베이스에 저장됩니다.

EntityManager em = ...;

User user = new User();
user.setName("Alice");

em.persist(user); // user는 새로운 엔티티로 간주됨

3. Spring Data JPA의 save() 메서드

Spring Data JPA의 save() 메서드는 내부적으로 새로운 엔티티인지 판단하여 다음과 같이 동작합니다:

  • 새로운 엔티티: persist() 호출.
  • 기존 엔티티: merge() 호출.

판단 기준

  1. 엔티티의 ID 필드가 null이면 새로운 엔티티로 판단.
  2. ID 필드가 null이 아니고, 데이터베이스에 존재하면 기존 엔티티로 판단.

예시 코드

User newUser = new User();
newUser.setName("Alice");

// 새로운 엔티티로 판단하여 persist() 호출
userRepository.save(newUser);

User existingUser = userRepository.findById(1L).orElseThrow();
existingUser.setName("Updated Name");

// 기존 엔티티로 판단하여 merge() 호출
userRepository.save(existingUser);

4. Spring Data JPA에서 새로운 엔티티인지 확인하는 방법

save() 메서드를 사용하지 않고 직접 새로운 엔티티인지 확인하려면 다음 방법을 사용할 수 있습니다.

(1) ID 필드 직접 확인

if (user.getId() == null) {
    System.out.println("새로운 엔티티입니다.");
} else {
    System.out.println("기존 엔티티입니다.");
}

(2) Persistable 인터페이스 구현

Persistable 인터페이스를 구현하여 새로운 엔티티인지 판단하는 로직을 커스터마이징할 수 있습니다.

import org.springframework.data.domain.Persistable;

@Entity
public class User implements Persistable<Long> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Override
    public Long getId() {
        return id;
    }

    @Override
    public boolean isNew() {
        // 새로운 엔티티 기준 정의 (예: id가 null이면 새로운 엔티티)
        return this.id == null;
    }
}

5. 주의사항

  1. 식별자 생성 전략

    • ID가 자동 생성(@GeneratedValue)되지 않고 애플리케이션에서 직접 할당할 경우, 새로운 엔티티 판단이 다르게 작동할 수 있습니다.
    • 예를 들어, ID를 직접 설정하면서 데이터베이스에 저장되지 않았다면 save() 호출 시 충돌이 발생할 수 있습니다.
  2. 준영속 상태 확인

    • 준영속 상태(detached)에서는 ID가 존재해도 merge()가 호출됩니다.
    • 새로운 엔티티와 혼동하지 않도록 상태를 명확히 구분해야 합니다.

요약

  • JPA는 ID가 null인 경우 새로운 엔티티로 판단합니다.
  • Spring Data JPA의 save()는 이를 바탕으로 persist() 또는 merge()를 호출합니다.
  • 커스터마이징이 필요할 경우 Persistable 인터페이스를 활용할 수 있습니다.

추가 학습 자료

profile
🌱

0개의 댓글