엔티티를 생성, 변경할 때 변경한 사람과 시간을 추적하는 기능이 대부분 있어야한다.
📕 순수 JPA 사용
📗 등록일, 수정일
[JpaBaseEntity]
@MappedSuperclass
public class JpaBaseEntity {
@Column(updatable = false)
private LocalDateTime createDate;
private LocalDateTime updateDate;
@PrePersist
public void prePersist() {
LocalDateTime now = LocalDateTime.now();
createDate = now;
updateDate = now;
}
@PreUpdate
public void preUpdate() {
updateDate = LocalDateTime.now();
}
}
생성 후 사용할 엔티티에 extends를 해준다.
public class Member extends JpaBaseEntity {}
끝!
확인 코드를 돌려보면 잘 적용되는걸 볼 수 있다.
@Test
public void jpaEventBaseEntity() throws Exception {
//given
Member member = new Member("member1");
memberRepository.save(member); //@PrePersist
Thread.sleep(100);
member.setUsername("member2");
em.flush(); //@PreUpdate
em.clear();
//when
Member findMember = memberRepository.findById(member.getId()).get();
//then
System.out.println("findMember.createdDate = " + findMember.getCreateDate());
System.out.println("findMember.updatedDate = " + findMember.getUpdateDate());
}
📗 JPA 주요 이벤트 어노테이션
- @PrePersist - 엔티티가 영속성 컨텍스트에 저장되기 전에 실행되는 메서드
- @PostPersist - 엔티티가 영속성 컨텍스트에 저장된 후에 실행되는 메서드
- @PreUpdate - 엔티티가 업데이트되기 전에 실행되는 메서드
- @PostUpdate - 엔티티가 업데이트된 후에 실행되는 메서드
📕 스프링 데이터 JPA 사용
📗 설정
- @EnableJpaAuditing -> 스프링 부트 설정 클래스에 적용해야함
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
}
- @EntityListeners(AuditingEntityListener.class) -> 엔티티에 적용
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
- 등록자, 수정자를 처리해주는 AuditorAware -> 스프링 빈 등록
- 실무에서는 세션 정보나, 스프링 시큐리티 로그인 정보에서 ID를 받음
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of(UUID.randomUUID().toString());
}
}
실무에서는 대부분의 엔티티는 등록시간, 수정시간이 필요하지만, 등록자, 수정자는 없을 수도 있다. 그래서 다음과 같이 Base 타입을 분리하고, 원하는 타입을 선택해서 상속한다.
public class BaseTimeEntity {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
public class BaseEntity extends BaseTimeEntity {
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
📗 사용 어노테이션
- @CreatedDate
- @LastModifiedDate
- @CreatedBy
- @LastModifiedBy