BaseTimeEntity.java
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updateAt;
}
@MappedSuperclass
- 객체의 입장에서 공통 매핑 정보가 필요할 때 사용
- id, name은 객체의 입장에서 볼 때 계속 나옴
- 이렇게 공통 매핑 정보가 필요할 때, 부모 클래스에 선언하고 속성만 받아서 사용하고 싶을 때 @MappedSuperclass를 사용
- DB 테이블과는 상관없다. 아래를 보면 DB는 매핑 정보 다 따로 사용하고 있다. 이는 객체의 입장
코드로 이해하기
- 생성자, 생성시간, 수정자, 수정시간을 모든 엔티티에 공통으로 가져가야 하는 상황에서 아래와 같이 BaseEntity를 정의해서 활용할 수 있음
- BaseEntity.java
- 매핑 정보만 상속받는 Superclass라는 의미의 @MappedSuperclass 어노테이션 선언
@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity{
private String createBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
}
@EntityListeners(AuditingEntityListener.class)
JPA Auditing이란?
Java에서 ORM기술인 JPA를 사용하여 도메인을 관계형 데이터베이스 테이블에 매핑할 때 공통적으로 도메인들이 가지고 있는 필드나 컬럼들이 존재한다. 대표적으로 생성일자, 수정 일자, 식별자 같은 필드 및 컬럼이 있다.
도메인마다 공통적으로 존재한다는 의미는 결국 코드가 중복된다는 말과 일맥상통함.
그래서 JPA에서는 Audit이라는 기능을 제공하고 있다. Audit은 Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능이다. 도메인을 영속성 컨텍스트에 저장하거나 조회를 수행한 후에 update를 한느 경우 매번 시간 데이터를 입력하여 주어야 하는데, audit을 이용하면 자동으로 시간을 매핑하여 데이터베이스의 테이블에 넣어주게 됨.
build.grade에 의존성 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.projectlombok:lombok'
}
어노테이션 | 설명 |
@MappedSuperclass | JPA Entity 클래스들이 해당 추상 클래스를 상속할 경우 컬럼들 인식 가능 |
@EntityListeners(AuditingEntityListener.class) | 해당 클래스에 Auditing 기능을 포함 |
@CreatedDate | Entity가 생성되어 저장될 때 시간이 자동 저장 |
@LastModifiedDate | 조회한 Entity의 값을 변경할 때 시간이 자동 저장 |
클래스 상속 example
@Getter
@NoArgsConstructor
@Entity
public class Posts extends BaseTimeEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
public void update(String title, String content) {
this.title = title;
this.content = content;
}
}
JPA Auditing 활성화
@EnableJpaAuditing
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Posts클래스가 @MappedSuperclass가 적용된 BaseTimeEntity 추상 클래스를 상속하기 때문에 JPA가 생성일자, 수정일자 컬럼을 인식하게 된다. 그리고 영속성 컨텍스트에 저장 후 BaseTimeEntity 클래스의 Auditing 기능으로 인해서 트랜잭션 커밋 시점에 플러시가 호출할 때 하이버네이트가 자동으로 시간 값을 채워주는 것을 확인할 수 있다.
스프링 부트의 Entry포인트인 실행 클래스에 @EnableJpaAuditing 어노테이션을 적용하여 JPA Auditing을 활성화 해야하는 것을 잊으면 안 된다.
참고
https://ict-nroo.tistory.com/129
https://webcoding-start.tistory.com/53
'Back-End > Study' 카테고리의 다른 글
DAO와 Repository 차이 (0) | 2022.08.10 |
---|---|
Lombok 라이브러리 어노테이션 (0) | 2022.08.04 |
JPAQueryFactory (0) | 2022.08.01 |
유효성 검사 - @NotNull @NotEmpty @NotBlank (0) | 2022.07.30 |
순환참조 해결 @JsonIgnore, @JsonManagedReference, @JsonBackReference (0) | 2022.07.29 |