EntityListeners
생성 · 수정일, 생성 · 수정자 같은 요소들은 엔티티에 거의 필수적으로 들어가는 요소들이다.
특히 생성 · 수정일은 거의 모든 엔티티에 들어가는 요소라고 해도 과언이 아니다.
하지만 DB에 엔티티가 생성, 수정될 때마다 해당 값을 일일이 넣어주는 것은 매우 반복적이고 지루한 일이다.
EntityListeners는 Jpa 엔티티에서 이벤트가 발생할 때마다 콜백을 처리할 수 있게 해 준다.
이는 생성, 수정과 관련된 요소들을 공통된 메서드로 처리할 수 있음을 뜻한다.
pongGame 프로젝트에서는 위와 같이 엔티티에서 반복되는 요소들에 특정 이벤트가 발생했을 때 EntityListeners를 통해서 자동적으로 처리하도록 한다.
또한 생성 · 수정일, delete 요소를 담은 클래스, 생성 · 수정자를 담은 클래스를 생성해서 엔티티에 따라 앞의 두 클래스를 상속받도록 해서 중복되는 코드를 줄인다.
1. EntityListeners
■ AuditingEntityListener 적용
EntityListeners를 사용할 때 콜백 함수가 구현된 AuditingEntityListener를 적용한다.
[AuditingEntityListener 적용]
@EnableJpaAuditing
@SpringBootApplication
public class HipoApplication {
public static void main(String[] args) {
SpringApplication.run(HipoApplication.class, args);
}
}
AuditingEntityListener를 사용하기 위해서는 main 클래스에 @EnableJpaAuditing을 적용해주어야 한다.
■ Base Class
생성, 수정, 삭제와 관련된 필드로 이루어진 Base 클래스를 만들고 엔티티가 Base 클래스를 상속하도록 한다.
□ BaseTime
[BaseTime]
@EntityListeners(AuditingEntityListener.class) //[1]
@MappedSuperclass //[2]
@Getter
public class BaseTime {
@CreatedDate //[3]
@Column(updatable = false) //[4]
private LocalDateTime createDate;
@LastModifiedDate //[5]
private LocalDateTime lastModifiedDate;
private boolean deleted = false; //[6]
public void softDelete() {
this.deleted = true;
}
}
엔티티 생성 · 수정 시간과 softDelete를 위한 delete를 필드로 갖는 클래스
● [1] : 어노테이션이 적용된 클래스에 AuditingEntityListener의 어노테이션을 사용할 수 있다.
ex) @CreatedDate, @LastModifiedDate 등
● [2] : 엔티티에서 테이블에 대한 공통 매핑 정보가 필요할 경우 부모 클래스로써 정의할 때 사용
해당 어노테이션이 붙은 클래스는 엔티티가 아니기 때문에 DB에 테이블로 매핑되지 않는다.
해당 클래스의 필드가 상속받아진 엔티티의 column에 매핑될 뿐이다.
● [3] : AuditingEntityListener의 어노테이션. 엔티티가 생성될 때를 캐치해 생성 시간을 넣어준다.
● [4] : 생성시간은 불변으로 설정해준다.
● [5] : 마지막 수정 시간 값을 캐치해서 해당 필드에 넣어주는 어노테이션
● [6] : softDelete 판단에 사용되는 필드 softDelete 된 엔티티는 해당 값이 true가 된다.
□ BaseBy
[BaseBy]
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseBy extends BaseTime {
@CreatedBy
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
엔티티 생성 · 수정자를 필드로 갖는 클래스
BaseTime을 상속받기 때문에 해당 클래스는 BaseTime에 요소가 더해져있다고 볼 수 있다.
따라서 해당 클래스는 BaseTime의 요소(생성일, 수정일, deleted)와, 생성자와 수정자를 column으로 가져야하는 엔티티에 상속되는 용도로 사용된다.
엔티티가 생성 · 수정될 때 AuditingEntityListner가 생성 · 수정자를 찾을 수 있도록 AuditorAware의 getCurrentAuditor()를 Override 해야 한다.
■ AppConfig
AuditingEntityListner가 생성 · 수정자를 찾을 수 있도록 AuditorAware의 getCurrentAuditor()를 Override 한다.
[AppConfig]
@Configuration
public class AppConfig {
@Bean
public AuditorAware<String> auditorProvider() {
return new AuditorAware<String>() {
@Override
public Optional<String> getCurrentAuditor() {
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal == "anonymousUser") {
return Optional.of(principal.toString());
}
return Optional.of(((UserAccount) principal).getAccount().getNickname());
}
};
}
}
□ auditorProvider
[auditorProvider]
@Bean //[1]
public AuditorAware<String> auditorProvider() {
return new AuditorAware<String>() {
@Override
public Optional<String> getCurrentAuditor() { //[2]
//[3]
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal == "anonymousUser") { //[4]
return Optional.of(principal.toString());
}
//[5]
return Optional.of(((UserAccount) principal).getAccount().getNickname());
}
};
}
● [1] : AuditorAware를 적용하기 위해, AuditorAware를 반환하는 메서드를 Bean으로 등록해준다.
● [2] : AuditorAware의 getCurrentAuditor()를 Override 해서 엔티티의 생성 · 수정자를 반환하도록 한다.
● [3] : 엔티티를 생성 · 수정했을 때 현재 로그인한 사용자를 SecurityContextHolder에서 찾는다.
● [4] : 익명 사용자일 경우 "anonymousUser"를 반환
● [5] : 인증된 사용자가 존재할 경우 사용자(Account)의 Nickname을 반환
□ Base Class 적용
[BaseTime 상속]
@Getter
@Entity
@Where(clause = "deleted = false")
public class Account extends BaseTime {
.
.
.
}
Account는 생성자와 수정자라는 요소가 필요없기 때문에 BaseTime을 상속받는다.
[Account의 column]
JPA를 사용해서 Account를 DB와 매핑시킬 경우 BaseTime의 필드들이 제대로 Column으로 들어와있는것을 확인 할 수 있다.
또한 Account를 생성 했을 때 시간이 createDate, lastModifiedDate에 자동으로 채워지게 된다.
'프로젝트 > PongGame' 카테고리의 다른 글
Account Repository (0) | 2022.05.10 |
---|---|
Account API 명세 (0) | 2022.05.05 |
LoginAccountIdArgumentResolver (0) | 2022.04.28 |
FileProcessor (0) | 2022.04.28 |
Spring Security, JWT, 인증, 인가 (5) | 2022.04.18 |
댓글