📌 등록일, 수정일은 무조건 모든 테이블에!!
이 4개의 기본적인 값을 적용하는 방법을 순수 JPA를 사용해서, 그리고 Spring Data JPA를 사용해서 적용을 어떻게 하는지 알아보자!
등록일
, 수정일
필드를 가지고 있는 JpaBaseEntity
@Getter
@MappedSuperclass // 진짜 상속관계는 아니고, 속성만 내려서 테이블에 넣어서 사용할 수 있게하는 것.
public class JpaBaseEntity {
@Column(updatable = false) // 등록일은 실수로라도 수정할 수 없도록
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
@PrePersist // persist하기 전에 이벤트가 발생
public void prePersist(){
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}
@PreUpdate
public void preUpdate(){
updatedDate = LocalDateTime.now();
}
}
JPA 주요 이벤트 어노테이션
@PrePersist
:Persist
하기 전에 이벤트 발생
@PostPersist
:Persist
한 후에 이벤트 발생
@PreUpdate
:Update
하기 전에 이벤트 발생
@PreUpdate
:Update
한 후에 이벤트 발생
속성(필드)들만 내려서 상속
받겠다.엔티티가 아니다
.공통으로 사용하는 매핑 정보
를 모으는 역할추상클래스
로 만드는 것을 권장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.getCreatedDate = " + findMember.getCreatedDate());
System.out.println("findMember.getUpdatedDate = " + findMember.getUpdatedDate());
}
@PrePersist, @PreUpdate 잘 작동!
🚨 이 설정을 잊지 않도록 주의!!
@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
}
@EnableJpaAuditing
: JPA의 Auditing 활성화보통
등록일, 수정일
은 기본적으로모든
테이블에 컬럼으로 들어가고,등록자, 수정자
는필요한
경우 사용한다.
BaseTimeEntity
- 등록일, 수정일
BaseEntity extends BaseTimeEntity
- 등록일, 수정일, 등록자, 수정자
위와 같이 만들어 필요한 것을 가져다 쓴다.
@EntityListeners(AuditingEntityListener.class)// 이벤트를 기반으로 동작함
@MappedSuperclass
@Getter
public class BaseTimeEntity {
// 등록일, 수정일
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
column
: 등록일, 수정일@EntityListeners
@CreatedDate
: Entity 생성되어 저장
될 때의 시간 자동 저장@LastModifiedDate
: 조회한 Entity의 값을 변경
할 때 시간을 자동 저장@EntityListeners(AuditingEntityListener.class)// 이벤트를 기반으로 동작함
@MappedSuperclass
@Getter
public class BaseEntity extends BaseTimeEntity{
// 등록자, 수정자 - DataJpaApplication에서 설정 필요(AuditorAware)
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
column
: 등록자, 수정자@EnableJpaAuditing
@SpringBootApplication
public class DataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DataJpaApplication.class, args);
}
// 등록자, 수정자 설정 필요
@Bean
public AuditorAware<String> auditorProvider(){
return new AuditorAware<String>() {
@Override
public Optional<String> getCurrentAuditor() {
return Optional.of(UUID.randomUUID().toString()); // 지금은 랜덤으로
}
};
}
}
등록, 수정될 때마다 AudiotorProvider 호출해서 결과물을 꺼내감.
참고!
실무에서는 세션 정보나, spring security 로그인 정보에서 ID를 받음.
@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.getCreatedDate = " + findMember.getCreatedDate());
System.out.println("findMember.getUpdatedDate = " + findMember.getLastModifiedDate());
System.out.println("findMember.getCreatedBy = " + findMember.getCreatedBy());
System.out.println("findMember.getLastModifiedBy = " + findMember.getLastModifiedBy());
}