728x90
반응형
💡 사용 계기
JPA Auditing 기능을 이용하여 데이터의 추가, 수정을 관리하였습니다.
그러나 @CreatedBy 와 @LastModifiedBy 를 통해 처음과 마지막 수정에 대해서만 알 수 있고, 중간 수정에 대해서는 알 수 없었습니다.
그래서 JPA Envers 기능을 추가하게 되었습니다.
📖 개념 정리
1. Envers
엔티티의 생성, 수정, 삭제 이력을 남길 수 있습니다.
Audit에 비해 모든 히스토리를 남기기 때문에 변경사항 추적할 수 있다는 점이 장점입니다.
하지만, 변경사항을 하나의 테이블에서 관리하기 때문에
추적해야하는 엔티티가 많은 경우 조회가 불편하다는 단점이 있습니다.
2. 한계
JPA가 자동으로 관리하기 때문에, 사용자 입력 데이터를 추가할 수 없습니다. (수정 사유 등)
💻 구현
1. 의존성 추가
dependencies {
...
implementation 'org.springframework.data:spring-data-envers:2.7.2'
}
2. RevisionEntity 생성
package com.cauh.common.entity;
import com.sun.istack.NotNull;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.envers.RevisionEntity;
import org.hibernate.envers.RevisionNumber;
import org.hibernate.envers.RevisionTimestamp;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@Data
@RevisionEntity(CustomRevisionEntityListener.class)
@Entity
@Table(name = "c_revision_info")
@Slf4j
public class CustomRevisionEntity implements Serializable {
private static final long serialVersionUID = ;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@RevisionNumber
private long rev;
@RevisionTimestamp
@Column(nullable = false)
private Long timestamp;
@Column(name = "modified_by", columnDefinition = "nvarchar(4000)")
private String modifiedBy;
@NotNull
public Date getRevisionDate() {
return new Date(timestamp);
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
}
3. CustomRevisionEntity에 유저 정보 저장
package com.cauh.common.entity;
import org.hibernate.envers.RevisionListener;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class CustomRevisionEntityListener implements RevisionListener {
@Override
public void newRevision(Object o) {
CustomRevisionEntity customRevisionEntity = (CustomRevisionEntity) o;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username = ((User)authentication.getPrincipal()).getUsername();
customRevisionEntity.setModifiedBy(username);
}
}
4. 추적하고자 하는 대상에, @Audit 추가
@Entity
@Audited
public class Board extends BaseEntity {
...
}
5. 추적하고자 하는 대상의 레포지토리 변경
@Repository
public interface BoardRepository extends JpaRepository<Board, Long>, RevisionRepository<Board, Long, Integer> {
...
}
6. 변경사항 추적 활성화
@SpringBootApplication
@EnableJpaAuditing
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
public class BoardApplication {
public static void main(String[] args) {
SpringApplication.run(BoardApplication.class, args);
}
}
💬 실행 화면
: 게시글 두개 작성 후, 첫번째 글을 수정하였습니다.
첫번째글을 "안녕하세요~~"에서 "안녕하세요~~!!!!"로 수정한 것을 알 수 있습니다.
728x90
반응형
'Web 개발 > Java, SpringBoot, JPA' 카테고리의 다른 글
[VSCode] Spring Boot 프로젝트 생성하는 방법 (0) | 2022.09.17 |
---|---|
[SpringBoot/Junit] No runnable methods Exception (0) | 2022.06.10 |
[jquery] Form submission canceled because the form is not connected (0) | 2022.04.20 |
[SPRING/JAVA] Apache Pdfbox를 이용한 PDF 수정3 - 글자 및 이미지 삽입 (0) | 2022.04.06 |
[SPRING/JAVA] Apache Pdfbox를 이용한 PDF 수정2 - 양식 (0) | 2022.04.05 |