엔티티 클래스에는 공통적으로 들어가는 필드가 있음
대표적으로 많이 사용되는 필드는 다음과 같음
이러한 필드들은 매번 엔티티를 생성하거나 변경할 때마다 값을 주입해야하는 번거로움이 있는데, Spring Data JPA에서는 이러한 값을 자동으로 넣어주는 기능을 제공함
JPA에서 'Audit'은 각 데이터마다 '누가', '언제' 데이터를 생성했고 변경했는지 감시한다는 의미로 사용됨
@SpringBootApplication
@EnableJpaAuditing
public class AdvancedJpaApplication {
public static void main(String[] args) {
SpringApplication.run(AdvancedJpaApplication.class, args);
}
}
하지만 위 방법은 테스트 코드를 작성해 테스트하는 일부 상황에서 오류가 발생할 수 있음 (@WebMvcTest를 지정해 테스트를 수행하면 애플리케이션 클래스 호출 과정에서 예외가 발생할 수 있음)
config/JpaAuditingConfiguration.java
@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}
각 엔티티에 공통으로 들어가게 되는 컬럼(필드)을 하나의 클래스로 빼는 작업 수행해야 함
먼저 생성 일자와 변경 일자만 추가해보자
data/entity/BaseEntity.java
@Getter
@Setter
@ToString
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
@CreatedDate // 데이터 생성 날짜를 자동으로 주입
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate // 데이터 수정 날짜를 자동으로 주입
private LocalDateTime updatedAt;
}
@MappedSuperclass: JPA의 엔티티 클래스가 상속받을 경우 자식 클래스에게 매핑 정보를 전달
@EntityListeners(AuditingEntityListener.class): 엔티티를 데이터베이스에 적용하기 전후로 콜백을 요청할 수 있게 하는 어노테이션 (AuditingEntityListener: 엔티티의 Auditing 정보를 주입하는 JPA 엔티티 리스너 클래스)
@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Table(name = "product")
public class Product extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long number;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private Integer price;
@Column(nullable = false)
private Integer stock;
}
이제 LocalDateTime.now() 같은 메서드를 사용해 시간을 주입하지 않아도 자동으로 값이 생성됨
※ 참고
callSuper 속성은 부모 클래스의 필드 포함 여부를 결정 (기본값: false)
추가로 @CreatedBy, @ModifiedBy 어노테이션도 존재하며, 누가 엔티티를 생성/수정했는지 자동으로 값을 주입함
이 기능을 사용하려면 AuditorAware를 스프링 빈으로 등록할 필요가 있음