JPA Auditing이란?
- Audit은 감시하다, 감사하다라는 뜻으로 Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능
- Entity를 update를 하는 경우 매번 modifiedAt에 시간 데이터를 입력해야 되는데, audit을 이용하면 자동으로 시간을 매핑하여 DB에 주입시킴
동작방식
- UserEntity가 @MappedSuperclass가 적용된 BaseEntity 추상 클래스를 상속
- JPA가 createdAt, modifiedAt 컬럼을 UserEntity의 컬럼으로 인식
- repository를 통해 영속성 컨텍스트에 저장
- EntityListener(Auditing) 기능으로 트랜잭션 커밋 시점에 Flush가 호출할 때, 인터럽트를 걸어서 하이버네이트가 시간 값을 채워줌
-> repository.save() 하기 전 시점에서는 BaseEntity 값이 null이지만, commit 후 DB에는 정상적으로 값이 들어감
사용 예제
1. build.gradle에 의존성 추가
dependencies{
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
2. Application.java에서 JPA Auditing 활성화
@SpringBootApplication
@EnableJpaAuditing
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. BaseEntity.java
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@Column(updatable = false)
@CreatedDate
private LocalDateTime createdAt;
@Column
@LastModifiedDate
private LocalDateTime modifiedAt;
}
Annotation | Description |
---|
@MappedSuperclass | JPA Entity 클래스들이 해당 추상 클래스를 상속할 경우 createDate, modifiedDate를 컬럼으로 인식 |
@EntityListeners(AuditingEntityListener.class | 엔티티를 DB에 적용하기 전, 이후에 커스텀 콜백(Auditing)을 요청 |
@CreatedDate | Entity가 생성되어 저장될 때 시간이 자동 저장 |
@LastModifiedDate | 조회한 Entity의 값을 변경할 때 시간이 자동 저장 |
4. UserEntity.java
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Entity
@Table(name="users")
public class User extends BaseEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String email;
@Column
private String password;
}
참고자료