p241
: JPA에서 Audit이란 감시하다라는 뜻
각 데이터마다 누가, 언제, 데이터를 생성하고 변경했는지 감시한다는 의미로 사용
: 프로젝트에 공통으로 들어가는 데이터 (ex : 생성일자, 변경일자)
대체적으로 많이 사용되는 내용
이러한 필드는 매번 엔티티를 생성하거나 변경할 때 마다 값을 주입해야하는 번거로움이 있다
: 스프링 부트 애플리케이션에 Auditing 기능 활성화
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 클래스를 생성해서 애플리케이션 클래스의 기능과 분리해서 활성화 시킨다
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing
public class JpaAuditingConfiguration {
}
: 코드의 중복을 제거하기 위해서 엔티티에 공통으로 들어가는 칼럼(필드)을 하나의 클래스로 빼준다
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;
}
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"));
}
}
@Embedded 어노테이션을 통해 분리
@Embedded
Base base