본문 바로가기

Programming!

Hibernate Envers 적용

Spring Boot 2.x + Spring Data JPA

특정 엔터티에 대해서 히스토리를 남겨야 하는 경우가 있다(비즈니스 요구사항 또는 시스템적으로..) 기존에는 해당 테이블의 히스토리 테이블을 만들어서 ObjectMapper등을 이용하여 json으로 변경한 후, 몇몇 정보와 함께 저장을 했었는데.

Hibernate Envers 이놈을 이용하면 그런 메뉴얼로 하는 작업들의 양을 줄일 수 있다.


다른것 필요없이 이것만 추가하면 된다.

compile('org.hibernate:hibernate-envers')



이후 history/log를 남겨야할 entity에 다음의 어노테이션을 추가하면 끝.

@Audited

@Cacheable

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class Company extends AuditingEntity implements Serializable {

...



그럼 몇가지 의문이 남는다.

그중 첫번째는 어떤식으로 history/log 테이블이 생기는가?.. 그건 hibernate의 'spring.jpa.hibernate.ddl-auto'에 의해서 결정되어 생성된다. 즉, create-drop.update로 하면 자동 생성되는 것이다. 그외 gradle plugin을 이용하는 방법도 있지만, 어짜피 운영에 적용 할때는 직접 create문을 따서 처리해야 할 듯하다.


There are several ways to create audit tables:


set hibernate.hbm2ddl.auto to create, create-drop or update, so Envers can create them automatically

use org.hibernate.tool.EnversSchemaGenerator to export the complete database schema programmatically

use an Ant task to generate appropriate DDL statements

use a Maven plugin for generating a database schema from your mappings (such as Juplo) to export Envers schema (works with Hibernate 4 and higher)


근데.. 내가 싫어하는 FK가 걸린다. 아...

Hibernate: 

    

    alter table company_AUD 

       add constraint FKavlit4ky8rlvoiku0y2ew9o7 

       foreign key (REV) 

       references REVINFO (REV)


두번째 의문.

부모클래스 AuditingEntity의 컬럼은 생성되지 않네..?

이경우는 부모클래스의  각 속성에 추가시켜주면 되기는 하는데..이건 좀 무..한 방법이다. 실행 클래스에 아래처럼 추가해주기만 하면 된다.


@Audited(auditParents = AuditingEntity.class)

@Cacheable

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class Company extends AuditingEntity implements Serializable {

...



각 테스트 코드를 돌려보면 아래처럼 생성된 table과 데이터를 볼 수 있다.




전체 코드 :  https://github.com/KimHyeongi 

관련 기사 : https://www.baeldung.com/database-auditing-jpa