엔티티 이력을 저장해주세요, envers 간단 사용기

June·2022년 12월 30일
6

실무 문제

목록 보기
2/10

학습 배경

현업에서의 개발은 학습 목적의 개발과 차이가 난다고 느껴지는 몇몇 포인트가 있다. 그런 것들 중 하나가 운영을 위한 코드나 기능들이 들어가야할 때가 있다는 점이다.

이번에도 주식 예언과 관련된 이벤트를 만들다가 사용자들의 데이터 변경 히스토리들을 다 저장해서 나중에 필요하면 볼 수 있게 해달라는 요청이 있었다. 이런거는 CS 대응을 위해서도 필요할 수도 있고, DA분들을 위해 필요할 수도 있다.

예전에 내가 들어오기전 진행된 프로젝트에서 비슷한걸 했다는걸 들었고 그걸 기반으로 사용해보기로 했다.

Envers

envers는 결국 쉽게 말해 엔티티가 변경될때 그 변경된 상태들이 또 다른 테이블에 하나하나 저장되는 것이다.

이번에 맡은 기능의 경우 예언 상태가 준비 상태 -> 예언할 수 있는 상태 -> 예언을 한 상태 -> 예언 결과가 나온 상태 -> 예언할 수 있는 상태 이런 사이클을 반복하기 때문에 envers로 관리하면 상태들을 추적할 때 편할 것이라 생각했다.

회사 코드를 올릴 수가 없어서 학습 목적으로 진행중인 프로젝트에서 진행을 했다. 기존 엔티티에 @Audited를 붙였다. 기존 Member 테이블이 있었는데 이제 변경 사항들은 MEMBER_AUD 테이블에 생성된다.

데이터를 변경하는 API를 호출해봤다. ROLE을 보면 USER -> ADMIN -> USER 로 변경해봤고 그 변경 내역들도 저장되어있다. 만약 Member 테이블에 createdAt, updatedAt 필드까지 있었다면 AUD 테이블의 createdAt을 보면 언제 변경되었는지 내역들을 다 알 수 있을 것이다.

REVTYPE은 0, 1, 2가 있는데 각각 생성 / 수정 / 삭제를 나타낸다.
REV는 트랜잭션 마다 생기는거다. (그 트랜잭션에서 변경이 일어나지 않는한)

revinfo 테이블에는 rev와 관련된 정보들이 또 따로 쌓이고 있는걸 알 수 있다.

회사 업무를 할때 MEMBER_AUD 테이블의 칼럼들을 not null로 했다가 예외가 발생했었다. 찾아보니 엔티티가 삭제될때 엔티티_AUD 테이블에는 속성들이 null로 저장되기 때문이다. 따라서 not null 제약을 없애줘야 한다. 그게 싫다면 org.hibernate.envers.store_data_at_delete=true 옵션을 주면 된다고 하는데 나는 AUD 테이블은 null을 열어줬다.

기타

  • 우리 팀에서는 백엔드 코드상에서는 aud 테이블을 바라보지 않기로 했다. DA 분들만 사용하실 것이기 때문에 aud 테이블 조회하는걸 따로 찾아보지 않았지만 영한님의 세션에서는 이 부분 관련 이야기도 해주셨다. 나중에 필요하면 찾아볼 계획이다.

  • 우테코 레벨 3 초반쯤에 jpa 관련 미션을 했다. 그때 어떤 '질문'을 삭제할 때 삭제 이력을 저장하는 비즈니스 요구사항이 있었는데, 어떤 관점에서는 엔티티를 지우는 것과 삭제하는 것이 섞여 있어 조금 어색하게 느껴졌는데 이번 envers를 통해서 해결할 수도 있겠다는 생각도 했다.

    하지만 엔티티의 상태가 자주 바뀐다해도 적절할지는 모르겠다. 영상에 나오는 것처럼 대규모 데이터라면 로그를 통해서 처리하는게 더 바람직할 수도 있겠다.

참고

1개의 댓글

comment-user-thumbnail
2022년 12월 31일

우와 이런 기능이 있었군요... 자주 사용될 수 있는 기능 같아요
감사합니다!!

답글 달기