Persisting Entities

2024. 10. 19. 19:08Spring Boot/Spring Data JPA

Spring Data JPA에서 엔티티를 저장하는 방법과, 엔티티의 상태를 감지하는 전략에 대해 설명합니다.

Saving Entities (엔티티 저장)

엔티티를 저장하는 방법은 CrudRepository.save(…) 메서드를 사용하는 것입니다. 이 메서드는 내부적으로 JPA의 EntityManager를 사용하여 주어진 엔티티를 저장하거나 병합합니다. 만약 엔티티가 아직 영속화되지 않은 상태라면, entityManager.persist(…)를 호출하여 저장하고, 이미 영속화된 엔티티라면 entityManager.merge(…)를 호출하여 병합합니다.

Entity State-detection Strategies (엔티티 상태 감지 전략)

Spring Data JPA는 엔티티가 새로운 것인지 아닌지 감지하는 몇 가지 전략을 제공합니다:

  1. Version-Property와 Id-Property 검사 (기본값):
    기본적으로 Spring Data JPA는 먼저 Version-property가 있는지 검사합니다. 만약 Version-property가 있고 그 값이 null이라면, 해당 엔티티는 새로운 것으로 간주됩니다. 만약 Version-property가 없다면, 엔티티의 식별자(Id-property)를 검사하여 그 값이 null이면 새로운 엔티티로 간주하고, 그렇지 않으면 기존 엔티티로 간주합니다.
  2. Persistable 인터페이스 구현:
    엔티티가 Persistable 인터페이스를 구현하면, Spring Data JPA는 엔티티가 새로운지 아닌지 감지하는 작업을 isNew(…) 메서드에 위임합니다. 이 메서드를 통해 엔티티가 새로운지 여부를 직접 판단할 수 있습니다.
  3. EntityInformation 구현:
    EntityInformation 추상화를 사용자 정의하는 방법도 있습니다. 이는 JpaRepositoryFactory의 서브 클래스를 생성하고 getEntityInformation(…) 메서드를 오버라이드하는 방식으로 구현할 수 있습니다. 이렇게 커스텀한 JpaRepositoryFactory를 Spring 빈으로 등록해야 합니다. 그러나, 이 방법은 일반적으로 거의 사용되지 않습니다.

주의 사항:

Option 1은 수동으로 식별자를 할당하는 엔티티에는 적합하지 않습니다. 식별자가 항상 null이 아닌 값을 가지기 때문입니다. 이러한 경우 일반적으로 @Transient로 선언된 플래그를 사용하여 새 엔티티인지 여부를 확인하는 공통 기반 클래스를 사용하는 패턴이 있습니다. JPA 생명주기 콜백을 사용하여 이 플래그를 저장 작업 이후 기존 엔티티로 전환하는 방식입니다.

예시 1: 수동으로 식별자를 할당하는 엔티티를 위한 공통 기반 클래스

@MappedSuperclass
public abstract class AbstractEntity<ID> implements Persistable<ID> {

  @Transient
  private boolean isNew = true;  // (1)

  @Override
  public boolean isNew() {
    return isNew;  // (2)
  }

  @PrePersist  // (3)
  @PostLoad
  void markNotNew() {
    this.isNew = false;
  }

  // 기타 코드…
}
  • (1) 엔티티가 새로운 상태인지 나타내는 플래그를 선언합니다. @Transient로 선언하여 이 플래그가 데이터베이스에 저장되지 않도록 합니다.
  • (2) Persistable.isNew() 메서드를 구현하여 이 플래그 값을 반환합니다. 이를 통해 Spring Data 리포지토리는 EntityManager.persist() 또는 EntityManager.merge()를 호출할지 결정할 수 있습니다.
  • (3) JPA 엔티티 콜백을 사용하여 엔티티가 저장된 이후, 또는 영속성 제공자에 의해 인스턴스가 생성된 후에 이 플래그를 false로 전환하는 메서드를 선언합니다.

이와 같은 방식으로 Spring Data JPA는 엔티티의 상태를 감지하고, 해당 엔티티가 새로운 경우 persist()를 호출하여 저장하거나, 기존 엔티티인 경우 merge()를 호출하여 병합합니다.

 


@PostLoad

@PostLoad 어노테이션은 JPA (Java Persistence API)에서 엔티티가 데이터베이스에서 로드된 후에 호출되는 메서드를 지정하는 데 사용됩니다. 이 어노테이션을 사용하면 엔티티의 상태를 초기화하거나 특정 작업을 수행할 수 있습니다.

주요 특징

  • 사용 시점: @PostLoad가 적용된 메서드는 엔티티가 데이터베이스에서 로드된 직후에 자동으로 호출됩니다. 이는 데이터베이스의 값을 엔티티로 가져오는 작업이 완료된 후에 이루어집니다.
  • 주로 사용하는 용도:
    • 엔티티의 속성을 초기화하거나 가공하는 데 사용됩니다.
    • 특정 상태를 플래그로 설정하는 데 유용합니다.
    • 엔티티가 로드된 후 추가적인 설정이나 로직을 실행할 때 사용됩니다.

예시 2

@Entity
public class User {

    @Id
    private Long id;
    private String username;

    @Transient
    private boolean isNew = true;

    @PostLoad
    void markNotNew() {
        this.isNew = false; // 엔티티가 로드된 후 isNew 플래그를 false로 설정
    }

    // Getter, Setter 등...
}

 

위 예시에서 User 엔티티가 데이터베이스에서 로드되면 markNotNew() 메서드가 호출되어 isNew 플래그가 false로 설정됩니다. 이 방법을 통해 엔티티의 상태를 관리하고 필요한 추가 로직을 적용할 수 있습니다.

'Spring Boot > Spring Data JPA' 카테고리의 다른 글

Query Lookup Strategies  (0) 2024.10.19
Defining Query Methods  (0) 2024.10.19
Configuration  (3) 2024.10.19
Defining Repository Interfaces  (0) 2024.10.19
Core concepts  (0) 2024.10.19