1. 문제 상황
Spring Data JPA를 사용해 엔티티를 설계하던 중, 생성일자(createdAt)를 어떻게 처리할지 고민했습니다.
처음에는 아래와 같이 작성했습니다:
// Member 엔티티의 createdAt 필드 부분
@Column(name = "created_at", nullable = false, updatable = false)
private final LocalDateTime createdAt = LocalDateTime.now();
이 방식은 코드가 간단하고 바로 초기화할 수 있다는 장점이 있었습니다. 하지만 아래와 같은 문제점이 있었습니다:
- 애플리케이션 실행 시점을 기준으로 값이 고정되며, 데이터베이스에 저장되는 정확한 시점과 다를 수 있음.
- 데이터베이스에 저장된 후에도 해당 필드를 다시 호출하거나 갱신할 일이 없을 것이라고 판단했기에, JPA가 굳이 이 필드를 관리할 필요가 없다고 생각했습니다.
- 그러나 이는 장기적으로 데이터의 정확성과 일관성을 떨어뜨릴 수 있다는 점을 깨달았습니다.
2. 개선된 코드와 @PrePersist 활용
이 문제를 해결하기 위해 @PrePersist를 사용했습니다.
private LocalDateTime createdAt;
@PrePersist
public void createdAt() {
this.createdAt = LocalDateTime.now();
}
@PrePersist란?
- JPA 엔티티 생명주기 이벤트 중 하나로, 엔티티가 영속화(persist) 되기 전에 실행되는 메서드에 붙이는 어노테이션입니다.
- 데이터베이스에 저장되는 정확한 시점의 값을 설정하는 데 유용합니다.
개선된 코드의 장점
- DB 저장 시점과 동기화
- 생성일자가 항상 데이터베이스에 저장되는 시점의 시간과 일치합니다.
- JPA에 초기화를 위임
- 생성일자 필드의 초기화 작업을 JPA가 처리하도록 위임함으로써, 코드의 가독성과 유지보수성을 높입니다.
- 데이터의 일관성
- 데이터베이스와 애플리케이션 간의 시간 차이로 인해 발생할 수 있는 오류를 방지할 수 있습니다.
3. 생성자 초기화와 @PrePersist 비교
방법 | 장점 | 단점 |
생성자 초기화 | 코드가 간단하고 즉시 초기화 가능 | 저장 시점과 다른 시간 저장 가능성 |
@PrePersist 사용 | 저장 시점 기준으로 데이터 일관성 유지 가능 | 생명주기와 영속화에 대한 학습 필요 |
4. 학습한 점과 교훈
처음에는 JPA가 굳이 이 필드를 관리할 필요가 없다고 생각했습니다.
"캐시에서 다시 날짜를 호출할 일이 없다면, 생성 시점에 바로 초기화하면 되지 않을까?"라는 단순한 접근 방식이었습니다.
그러나 실제로 데이터베이스에 저장되는 시점과 객체 생성 시점 사이의 시간 차이를 고려하지 못했습니다.
또한, JPA의 생명주기 이벤트를 활용하면 데이터의 일관성과 정확성을 더 잘 보장할 수 있다는 점을 깨달았습니다.
5. 테스트 코드로 검증하기
아래 테스트 코드를 통해 @PrePersist가 예상대로 동작하는지 검증할 수 있습니다:
@Test
void testPrePersist() {
Entity entity = new Entity(); // 엔티티 생성
entityRepository.save(entity); // 영속화
assertNotNull(entity.getCreatedAt()); // createdAt이 null이 아닌지 확인
assertTrue(entity.getCreatedAt().isBefore(LocalDateTime.now())); // 현재 시간보다 이전인지 확인
}
6. 결론
- @PrePersist를 활용하면 JPA의 엔티티 생명주기를 통해 데이터의 정확성과 일관성을 유지할 수 있습니다.
- 생성일자 초기화처럼 간단해 보이는 문제도 JPA의 기능을 잘 이해하고 활용하면 더 효율적으로 해결할 수 있습니다.
- 이번 경험을 통해, 애플리케이션과 데이터베이스 간의 데이터 처리 일관성을 유지하는 방법과 JPA의 강력한 생명주기 관리 기능에 대해 배울 수 있었습니다.
'문제 및 해결' 카테고리의 다른 글
[Spring JPA] 영속성 동작하지 않을 때의 원인과 해결법 (0) | 2024.12.16 |
---|---|
[VUE] 카카오 맵 api... 로딩 안되는 문제 해결 (0) | 2024.12.07 |
JavaScript에서 console.log에 객체를 출력하면 [object Object]로 표시 될 때 (0) | 2024.12.07 |
JPA 상속 클래스로 엔티티 중복 코드 제거하기 (0) | 2024.11.27 |
이미지가 많아져서 웹사이트가 느리다면?? (2) | 2024.11.14 |