Spring 프로젝트의 요구사항에 엔티티의 생성일 또는 수정일이 필요하다면 어떻게 해야 할까?
하나하나 만들어 보자.
1. 생성일 필드만 만든다고 가정 - @CreationTimeStamp / @Temporal 어노테이션에 대해 학습하기
먼저 생성일 필드만 추가한다고 가정해 보자. 생성일 필드는 createdAt(또는 적절한 이름의 필드) Date 필드를 만들고, @CreationTimeStamp, @Temporal 어노테이션을 선언하여 작성한다. 각각 어노테이션의 역할을 알아보자.
- @CreationTimeStamp 어노테이션 : 엔티티 인스턴스가 데이터베이스에 삽입될 때 생성되는 TimeStamp 이다.
- @Temporal 어노테이션 : 데이터베이스 테이블에 TimeStamp 필드를 매핑할 때, 매핑 유형을 지정하기 위해 사용한다. JPA 에서는 TemporalType.DATE (→ 날짜만 매핑), TemporalType.TIME (→ 시간만 매핑) , TemporalType.TIMESTAMP (→ 날짜와 시간 모두 매핑) 세 가지 유형을 매핑할 수 있다.
@Temporal(TemporalType.TIMESTAMP)
즉, @CreationTimeStamp 어노테이션만으로 생성시간 필드를 작성할 수 있으며, @Temporal 어노테이션은 테이블의 Date 필드의 유형을 지정하는 보조 역할을 한다. @CreationTimeStamp 만 사용하면 TimeStamp 형식으로 날짜, 시간 정보가 모두 저장된다. - 작성일 필드의 @Column 주석 내부에서 updatable 옵션을 false 로 설정할 수 있다. 해당 옵션을 false 로 설정하면, 데이터베이스 테이블에서 해당 필드가 SQL UPDTATE 문의 대상이 되지 않음을 지정한다.
@Column(name = "created_at", nullable = false, updatable = false)
따라서 Entity 클래스 내에 아래 속성을 가진 필드를 추가함으로써 생성일을 추가할 수 있다.
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
var createdAt: Date? = null
2. TimeStamp 클래스를 MappedSupperClass 로 지정하고, Entity 클래스가 이를 상속
만약 생성일이 필요한 Entity가 여러 개라고 하면, 위 생성일 작성 부분의 코드가 중복되게 된다. 그래서 생성일 필드만 담고 있는 TimeStamp 클래스를 만들고, 생성일이 필요한 Entity 가 이를 상속하도록 만들 수 있다. 이를 위해서 @MappedSupperClass 어노테이션에 대해 간단히 학습해 보자.
- @MappedSupperClass 는 정확히 위에서 언급한 것과 동일한 용도로 사용된다. 즉, 중복되는 필드가 작성되는 것을 방지하고 자신을 상속받는 것 만으로 해당 엔티티 테이블에 자신이 가진 필드를 매핑할 수 있게 해준다.
@Getter
@Setter
@MappedSuperclass
open class TimeStamp {
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
var createdAt: Date? = null
}
여기서 부모가 되는 TimeStamp 클래스도 마찬가지로 Entity 의 일종이라 할 수 있지만, 부모 클래스의 필드는 데이터베이스 테이블로 매핑되지 않는다.
@Entity
class Task(
var taskTitle : String,
var taskDetails : String,
var userName : String,
) : TimeStamp() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
var id: Long? = null
}
Task 클래스가TimeStamp 클래스를 상속받는 것 만으로, 테이블에 생성일 필드를 가지게 되었다.
(@MappedSupperClass 에 대해 더 자세한 내용은 다음에 다시 다뤄보겠다)
3. TimeStamp 클래스에 modifiedAt 필드를 추가하여 수정일 생성 (@UpdateTimeStamp 사용)
생성일과 거의 비슷한 방법으로 수정일(갱신시간)도 추가할 수 있다. 이때 필드에 사용하는 것은 @UpdateTimeStamp 어노테이션이다.
- @UpdateTimeStamp 어노테이션 : 필드가 수정될 때 변경 시간을 기록하는 TimeStamp
@Getter
@Setter
@MappedSuperclass
open class TimeStamp {
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
var createdAt: Date? = null
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "modified_at", nullable = false)
var modifiedAt: Date? = null
}
간단하게 TimeStamp 클래스에 modifiedAt 필드를 만들고 @UpdateTimeStamp 어노테이션을 추가해 주었다.
4. 서버 시간대 한국시간으로 설정
서버 시간이 한국시간이 아니고 몇시간 전의 시간으로 나온다면, application.yaml ( application.properties ) 파일 설정을 통해 해결 할 수 있다. 가장 간단하게 해결했던 방법은 JDBC URL 을 수정하는 것이었다.
※ 수정) 마지막에 소개한 application.yaml 의 JDBC URL 의 서버 주소를 한국 서버로 변경하는 방법은 데이터베이스에 저장된 Date 값이 한국 시간으로 변경되지만, 조회 요청의 응답으로 이를 받아올 때는 한국시간이 적용되지 않는 것이 확인되었다. 곧 다른 방법을 찾아보고 적용하여 공유할 예정이다.
이로써 테이블에 생성일/ 수정일 필드를 추가하고, 중복 코드를 관리하기 위한 방법까지 알아봤다.
'Study' 카테고리의 다른 글
[Java]가비지 컬렉션(GC) (0) | 2024.05.22 |
---|---|
[Spring]ResponseEntity 사용법과 사용하는 이유 (0) | 2024.05.20 |
스레드(2) - SpringBoot (Tomcat) 에서의 멀티스레딩 (0) | 2024.05.08 |
숫자야구 (0) | 2024.05.07 |
스레드(Thread) (0) | 2024.05.01 |