Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 인프런
- Greedy
- SpringBoot
- pointcut
- transaction
- Exception
- 김영한
- kotlin
- Proxy
- http
- 스프링 핵심 기능
- Thymeleaf
- 그리디
- AOP
- 자바
- Servlet
- db
- 백준
- JDBC
- 스프링
- 스프링 핵심 원리
- spring
- Android
- java
- QueryDSL
- springdatajpa
- Spring Boot
- JPQL
- jpa
- 알고리즘
Archives
- Today
- Total
개발자되기 프로젝트
Auditing 본문
1. Auditing
- 엔티티를 생성 및 변경할 때 변경한 사람과 시간을 추적하고 싶으면?
- 등록일
- 수정일
- 등록자
- 수정자
2. JPA 활용
- JpaBaseEntity
- @MappedSuperclass
- Designates a class whose mapping information is applied to the entities that inherit from it.
- A mapped superclass has no separate table defined for it.
- 해당 annotation은 상속받는 엔티티에 매핑 정보를 전달할 클래스를 지정.
- 즉, 해당 annotation이 붙은 클래스의 속성 정보만 하위 클래스에 전달하여 하위클래스에서 사용할 수 있음.
- 해당 annotation이 붙은 클래스는 별도 table을 갖지 않음.
@MappedSuperclass //단순히 속성만 내려거 하위 클래스에서 사용할 수 있도록 함.
public class JpaBaseEntity {
@Column(updatable = false)
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
@PrePersist
public void prePersist(){
LocalDateTime now = LocalDateTime.now();
createdDate = now;
updatedDate = now;
}
@PreUpdate
public void preUpdate(){
updatedDate = LocalDateTime.now();
}
}
- Member
- JpaBaseEntity를 상속받음
- 상속을 받음으로서 @MappedSuperclass에 의해 JpaBaseEntity의 속성을 사용할 수 있다.
public class Member extends JpaBaseEntity{
- Member table에 JpaBaseEntity의 속성이 추가됨.
create table member (
member_id bigint not null,
created_date timestamp,
updated_date timestamp,
age integer not null,
user_name varchar(255),
team_id bigint,
primary key (member_id)
)
- Test
@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());
}
findMember.getCreatedDate() = 2021-08-30T23:15:48.054363
findMember.getUpdatedDate() = 2021-08-30T23:15:48.235787
3. JPA 주요 이벤트 annotation
- @PrePersist, @PostPersist
- @PreUpdate, @PostUpdate
4. SpringDataJPA 활용
- 설정
- @EnableJpaAuditing 스프링 부트 설정 클래스에 적용해야함
@SpringBootApplication @EnableJpaAuditing public class SpringDataJpaApplication { public static void main(String[] args) { SpringApplication.run(SpringDataJpaApplication.class, args); } }
- @EntityListeners(AuditingEntityListener.class) 엔티티에 적용
- @EntityListeners(AuditingEntityListener.class) : 엔티티 리스너로 등록
- 와 간단
@EntityListeners(AuditingEntityListener.class) @MappedSuperclass @Getter public class BaseEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime lastModifiedDate; }
- @EnableJpaAuditing 스프링 부트 설정 클래스에 적용해야함
- Member Class
- 기존 JpaBaseEntity를 BaseEntity로 변경
public class Member extends BaseEntity{
5. 등록자 수정자
- 등록자, 수정자를 처리해주는 AuditorAware 스프링 빈 등록이 필요하다.
- AuditorAware를 등록해야 @CreatedBy, @LastModifiedBy 실행 시 빈에서 찾아서 값을 채움.
- 아래 예시는 임의의UUID 생성.
@SpringBootApplication
@EnableJpaAuditing
public class SpringDataJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataJpaApplication.class, args);
}
@Bean
public AuditorAware<String> auditorProvider(){
return () -> Optional.of(UUID.randomUUID().toString());
}
}
- BaseEntity
- @CreatedBy, @LastModifiedBy
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
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;
}
- Test
@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.getCreatedBy() = " + findMember.getCreatedBy());
System.out.println("findMember.getUpdatedDate() = " + findMember.getLastModifiedDate());
System.out.println("findMember.getLastModifiedBy() = " + findMember.getLastModifiedBy());
}
- Result
findMember.getCreatedDate() = 2021-08-30T23:31:41.942533
findMember.getCreatedBy() = 019d4f5d-1044-493c-907f-dab3ed319c78
findMember.getUpdatedDate() = 2021-08-30T23:31:42.100038
findMember.getLastModifiedBy() = ee981afd-42fe-4800-93a5-aec0255ff306
6. 참고
- 실무에서 대부분의 엔티티는 등록시간, 수정시간이 필요하지만,
- 등록자, 수정자는 없을 수도 있다.
- 그러면 time과 관련된 Base 타입을 분리해두자.
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity extends BaseTimeEntity{
@CreatedBy
@Column(updatable = false)
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
}
7. GitHub : 210830 Auditing
'인프런 > [인프런] Spring Data JPA' 카테고리의 다른 글
SpringDataJpa의 구현체 (0) | 2021.08.31 |
---|---|
Web 확장 : 도메인 클래스 컨버터, 페이징 & 정렬 (0) | 2021.08.31 |
사용자 정의 Repository (0) | 2021.08.30 |
JPA Hint & Lock (0) | 2021.08.29 |
@EntityGraph (0) | 2021.08.29 |
Comments