2024. 10. 19. 19:08ㆍSpring Boot/Spring Data JPA
Spring Data JPA에서 엔티티를 저장하는 방법과, 엔티티의 상태를 감지하는 전략에 대해 설명합니다.
Saving Entities (엔티티 저장)
엔티티를 저장하는 방법은 CrudRepository.save(…)
메서드를 사용하는 것입니다. 이 메서드는 내부적으로 JPA의 EntityManager
를 사용하여 주어진 엔티티를 저장하거나 병합합니다. 만약 엔티티가 아직 영속화되지 않은 상태라면, entityManager.persist(…)
를 호출하여 저장하고, 이미 영속화된 엔티티라면 entityManager.merge(…)
를 호출하여 병합합니다.
Entity State-detection Strategies (엔티티 상태 감지 전략)
Spring Data JPA는 엔티티가 새로운 것인지 아닌지 감지하는 몇 가지 전략을 제공합니다:
- Version-Property와 Id-Property 검사 (기본값):
기본적으로 Spring Data JPA는 먼저 Version-property가 있는지 검사합니다. 만약 Version-property가 있고 그 값이 null이라면, 해당 엔티티는 새로운 것으로 간주됩니다. 만약 Version-property가 없다면, 엔티티의 식별자(Id-property)를 검사하여 그 값이 null이면 새로운 엔티티로 간주하고, 그렇지 않으면 기존 엔티티로 간주합니다. - Persistable 인터페이스 구현:
엔티티가Persistable
인터페이스를 구현하면, Spring Data JPA는 엔티티가 새로운지 아닌지 감지하는 작업을isNew(…)
메서드에 위임합니다. 이 메서드를 통해 엔티티가 새로운지 여부를 직접 판단할 수 있습니다. - 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 |