공통 기능 - JPA Auditing

Welcome to Seoyun Dev Log·2022년 12월 8일
0

Auditing

  • p241
    : JPA에서 Audit이란 감시하다라는 뜻
    각 데이터마다 누가, 언제, 데이터를 생성하고 변경했는지 감시한다는 의미로 사용
    : 프로젝트에 공통으로 들어가는 데이터 (ex : 생성일자, 변경일자)

  • 대체적으로 많이 사용되는 내용

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

이러한 필드는 매번 엔티티를 생성하거나 변경할 때 마다 값을 주입해야하는 번거로움이 있다

  • spring data JPA에서는 이런 값을 자동으로 넣어주는 기능을 제공

Auditing 기능 활성화

: 스프링 부트 애플리케이션에 Auditing 기능 활성화

  • main() 메서드가 있는 클래스에 @EnableJpaAuditing 어노테이션 추가 (테스트 환경에서 권장하지 않음)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class HospitalMustacheProjectApplication {

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

}

기능은 활성화 되었지만, @WebMvcTest로 테스트를 진행할 경우 애플리케이션 클래스를 호출하는 과정에서 오류가 발생할 수 있다

그래서 별도의 Configuration 클래스를 생성해서 애플리케이션 클래스의 기능과 분리해서 활성화 시킨다

⭐️ 1. Configuration 분리

  • 애플리케이션 클래스의 @EnableJpaAuditing 삭제해야 정상 작동
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}

2. BaseEntity 클래스 만들기

: 코드의 중복을 제거하기 위해서 엔티티에 공통으로 들어가는 칼럼(필드)을 하나의 클래스로 빼준다

  • 예제 ) 생성 일자, 변경 일자만 추가
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@MappedSuperclass//JPA의 엔티티 클래스가 상속받을 경우 자식 클래스에게 매핑 정보를 전달
@EntityListeners(AuditingEntityListener.class)//엔티티를 데이터베이스에 적용하기 전후로 콜백을 요청할 수 있게하는 어노테이션
public class BaseEntity {

    @CreatedDate//데이터 생성 날짜를 자동으로 주입하는 어노테이션
    @Column(updatable = false)
    private LocalDateTime createAt;

    @LastModifiedDate//데이터 수정 날짜를 자동으로 주입하는 어노테이션
    private LocalDateTime updateAt;
    
}
  • AuditingEntityListener.class : 엔티티의 Auditing 정보를 주입하는 JPA 엔티티 리스너 클래스
  • dateTIme format : https://mchch.tistory.com/165

BaseEntity 클래스 상속 받기

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Getter
@Entity
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "t_visit")
public class Visit extends BaseEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "visit_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id")
    @JsonIgnore
    private Hospital hospital;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    @JsonIgnore
    private Users users;

    @Column(name = "disease")
    private String disease;

    @Column(name = "amount")
    private float amount;

    /*@Column(name = "create_date")
    private String createDate;*/

    public Visit(Hospital hospital, Users users, String disease, float amount) {
        this.hospital = hospital;
        this.users = users;
        this.disease = disease;
        this.amount = amount;
        //this.createDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

}

02. 방법 2

@Embedded 어노테이션을 통해 분리

  • Base class를 만들고 적용할 해당 엔티티에 어노테이션을 달아준다
@Embedded
Base base

03. 방법 3

  1. class 생성
profile
하루 일지 보단 행동 고찰 과정에 대한 개발 블로그

0개의 댓글