@CreatedDate
)에 의해 강제 갱신되는 created_at
필드를 직접 제어하여, 과거 시점의 주문을 DB에 삽입초기 시도
DataInitializer
에서 리플렉션으로 Order
엔티티의 createdAt
필드 세팅orderRepository.save(order)
호출문제 발생
@CreatedDate
어노테이션을 기반으로 항상 현재 시각으로 덮어씀Spring Data JPA의 AuditingEntityListener
@CreatedDate
필드에 자동으로 현재 시각을 주입방안 | 장점 | 단점 |
---|---|---|
1) Auditing 비활성화(실행 컨텍스트 내) | JPA 사용 유지 간단 설정 | 애플리케이션 전체 영향 가능성 소스 코드·설정 추가 필요 |
2) 별도 엔티티 매니저/Repository 사용 | Auditing 적용 안 함 JPA API 호환 | 설정 복잡 관리 부담 |
3) JdbcTemplate 직접 SQL 삽입 | Auditing 완전 우회 SQL로 원하는 값 바로 삽입 | SQL 하드코딩 Entity 일관성 주의 필요 |
→ 3번 선택: 간단하고 확실하게 Auditing을 우회
의존성 추가
<!-- build.gradle 예시 -->
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
JdbcTemplate 빈 주입
@Component
public class DataInitializer {
private final JdbcTemplate jdbcTemplate;
public DataInitializer(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
}
createOrderWithTimestamp()
메서드 변경
private void createOrderWithTimestamp(Long userId, Long productId, int quantity, LocalDateTime createdAt) {
String sql = "INSERT INTO orders (user_id, product_id, quantity, created_at, updated_at, created_by, updated_by) " +
"VALUES (?, ?, ?, ?, ?, ?, ?)";
jdbcTemplate.update(sql,
userId,
productId,
quantity,
Timestamp.valueOf(createdAt), // 직접 설정한 과거/현재 시각
Timestamp.valueOf(createdAt), // updated_at도 동일하게
"system", // created_by
"system" // updated_by
);
}
샘플 데이터 분포
Auditing 어노테이션 유지 여부
DB 직접 조회
SELECT product_id, COUNT(*) AS cnt
FROM orders
WHERE created_at BETWEEN NOW() - INTERVAL '30' DAY AND NOW()
GROUP BY product_id
ORDER BY cnt DESC
LIMIT 3;