[Spring] JPA Auditing 적용

WOOK JONG KIM·2022년 11월 1일
0
post-thumbnail

JPA Auditing

누가,언제 데이터를 생성하였고 변경했는지 감시

대표적으로 많이 사용하는 필드

  • 생성 주체
  • 생성 일자
  • 변경 주체
  • 변경 일자

이러한 필드는 매번 엔티티를 생성하거나 변경할 때마다 값을 주입해야 하는 번거로움 있음
-> 이를 해소하기 위해 자동으로 값을 넣어주는 기능 제공

JPA Auditing 기능 활성화

main() 메서드가 있는 클래스에 @EnableJpaAuditing 어노테이션을 추가

@SpringBootApplication
@EnableJpaAuditing
public class AdvancedJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(AdvancedJpaApplication.class, args);
    }

}

이렇게 할 경우 애플리케이션을 테스트하는 일부 상황에는 오류가 발생할 수도 있음
-> @WebMvcTest 어노테이션을 지정해서 테스트를 수행하는 코드 작성 시 애플리케이션 클래스를 호출하는 과정에서 예외 발생
-> 별도의 Configuration 클래스를 생성해서 애플리케이션 클래스의 기능과 분리해서 활성화 가능

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}

이렇게 할 시 메인에 지정하였던 어노테이션은 지워야 정상 동작

BaseEntity 만들기

코드의 중복을 없애기 위해 각 엔티티에 공통으로 들어가게 되는 칼럼을 하나의 클래스로 빼는 작업을 수행 해야 함

우선 생성 일자와 변경일자를 추가해서 BaseEntity를 추가하였음

@Getter
@Setter
@ToString
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {
    
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdAt;
    
    @LastModifiedDate
    private LocalDateTime updatedAt;
}
  • @MappedSuperClass : 엔티티 클래스가 상속받을 경우 자식 클래스에게 매핑 정보 전달
  • @EntityListeners : 엔티티를 데이터베이스에 적용하기 전후로 콜백을 요청할 수 있게 하는 어노테이션
  • AuditingEntityListener : 엔티티의 Auditing 정보를 주입하는 JPA 엔티티 리스너 클래스
  • @CreatedDate : 데이터 생성 날짜를 자동으로 주입하는 어노테이션
  • @LastModifiedDate : 데이터 수정 날짜를 자동으로 주입하는 어노테이션

이후 Product 엔티티 클래스에서 공통 칼럼을 제거

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(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;

    // private LocalDateTime createdAt;

    // private LocalDateTime updatedAt;

}

callSuper 속성은 부모 클래스의 필드를 포함하는 역할

@Test
    public void auditingTest(){
        Product product = new Product();
        product.setName("펜");
        product.setPrice(1000);
        product.setStock(100);

        Product savedProduct = productRepository2.save(product);

        System.out.println("productName :" + savedProduct.getName());
        System.out.println("createdAt :" + savedProduct.getCreatedAt());
productName :펜
createdAt :2022-11-01T14:28:59.161427

엔티티에 일자를 기입하지 않아도 정상적으로 DB에 생성일자가 저장되었음

profile
Journey for Backend Developer

0개의 댓글