글 작성자: 개발섭

Spring Data Enver란?

어플리케이션을 만들고, 결국 운영 및 관리를 해야 하는 입장에서는 활동로그성 데이터들이 필요하다. "누가" 그리고 "언제" 무엇을 "어떻게" 했는지가 중요한 데이터가 되기 때문에, 그런 기록을 반드시 필요로 하는 상황이 생긴다.
즉, 이러한 문제를 해결하기 위해서는 Audit(감사) 기능을 필요로 하게 되는데, 일단 데이터의 변경 이력을 관리하기 쉽게 해주는 Library를 찾았다.

spring data envers는 하이버네이트의 enver의 이력 로깅 기능을 가져와 JPA에서도 훨씬 편리한 방향으로 개발할 수 있도록 도와주는 툴이다.
의존성을 Spring Data Enver를 설치한뒤,


implementation 'org.springframework.data:spring-data-envers:3.4.4'

단순하게 이렇게만 해도...

@Entity
@Audited
public class Sample {

자동적으로 JPA Entity에 대한 Auditing이 가능해진다. 또한 Repository에 대한 큰 변경 혹은 Entity에 대한 생성없이도, 기능적으로는 이 버젼 관리에 집중할 수 있습니다.

public interface SampleRepository extends JpaRepository<Sample, Long>, RevisionRepository<Sample, Long, Integer> { }

RevisionRepository만 다중상속해버리면 → revision 객체를 통해서 내 이전 이력들을 확인할 수 있어진다.

그럼 이런식으로 레포지토리에서 찾아서 사용한다.

Revision<Long, Sample> revision = repository.findRevision(sample.getId(), 1); 

Sample entity = revision.getEntity(); // 엔티티 
Long revisionNumber = revision.getRevisionNumber(); // 리비전 
DateTime dateTime = revision.getRevisionDate(); // 변경 날짜

그리고 기본적으로는 이런형태의 Scheme를 취하지만..


create table Customer (
    id bigint not null,
    created_on timestamp,
    firstName varchar(255),
    lastName varchar(255),
    primary key (id)
)

create table Customer_AUD (
   id bigint not null,
    REV integer not null,
    REVTYPE tinyint,
    REVEND integer,
    created_on timestamp,
    firstName varchar(255),
    lastName varchar(255),
    primary key (id, REV)
)

create table REVINFO (
    REV integer generated by default as identity,
    REVTSTMP bigint,
    primary key (REV)
)

alter table Customer_AUD
    add constraint FK5ecvi1a0ykunrriib7j28vpdj
    foreign key (REV)
    references REVINFO

alter table Customer_AUD
    add constraint FKqd4fy7ww1yy95wi4wtaonre3f
    foreign key (REVEND)
    references REVINFO

근데 configuration 좀더 추가하면 디테일한 옵션도 추가 가능해져서 더 구체적으로 값을 변경지점을 확인할 수도 있는데...


flag나 old & new와 같은 값을 저장할 수도 있다.

아쉽게도 트랜잭션 단위의 통합 Revision 관리 (Snapshot) 에 가깝기 때문에 이게 로깅으로써의 역할보다는 백업 역할이 더 큰 것 같다는 점이다.
왜냐하면, 일단 기본적으로 Table Column의 전체적인 복사가 이뤄지기 때문에, 사실상 Table을 두개나가지고 있다는 점이며, 그 Table을 두개나 가지고 있다는 것은 사실 로그성이라기보다는... Backup성의 데이터에 가깝다고 생각이 든다.

물론, 이런것이 필요한 케이스들이 있긴 하겠지만, 실제로 지금 개발해야하는것은 Audit보다는 activity Log에 가까워서 그 값에 대해서 굳이 많이 가지고 있을 필요는 없다고 판단해 이건 나중에 적용하는 걸로 되었다.

출처