sábado, 25 de maio de 2019

Usando Hibernate Envers para auditoria


Pra quem não conhece o Hibernate Envers é o módulo de auditoria e versionamento de entidades. Neste post vou mostrar como configurar o envers no Spring Boot.

Primeiro precisamos adicionar a dependência do Envers no POM do nosso projeto:

<dependency>
     <groupId>org.hibernate</groupId>
     <artifactId>hibernate-envers</artifactId>
     <version>5.3.1.Final</version>
</dependency>

Precisamos também criar uma tabela padrão do Envers chamada “REVINFO” com dois campos, um ID e um campo pra guardar o timestamp das alterações:
  
CREATE TABLE revinfo (
rev integer NOT NULL,
revtstmp bigint,
CONSTRAINT revinfo_pkey PRIMARY KEY (rev)
)

Note que o campo para guardar a chave de revisão por padrão é um integer, para mudar para bigint é preciso fazer customização do Envers, criando uma entidade que contenha o campo do tipo Long como abaixo:

@Entity
@RevisionEntity
public class EntityRevisionCustom implements Serializable {
 
  @Id
  @GeneratedValue
  @RevisionNumber
  private Long rev;

  @RevisionTimestamp
  private Long timestamp;

  /* getts and setts */
}

Agora o SQL que cria a tabela passa a ser assim:

CREATE TABLE revinfo (

rev bigint NOT NULL,
revtstmp bigint,
CONSTRAINT revinfo_pkey PRIMARY KEY (rev)
)


Outra coisa que leva a criação dessa classe customizada é poder colocar mais informações nela, como por exemplo o usuário logado, que é o responsável pela alteração. Para isto é preciso criar um listener que possa pegar esse usuário e settar na entidade de forma transparente para o desenvolvedor.

Isso requer que informemos o Listener na classe customizada:

@Entity
@RevisionEntity(MyRevisionListener.class)
public class EntityRevisionCustom implements Serializable {
...
}

          Segue o exemplo de um listener que pega o usuário da sessão e preenche na classe customizada:

public class MyRevisionListener implements RevisionListener {
    @Override
    public void newRevision(Object revisionEntity) {
        EnversCustomRevision rev = (EnversCustomRevision) revisionEntity;
        rev.setUsuCodUsuario(SessionBean.getCodUsuarioLogado());
    }
}

Depois de adicionar a dependência e criar a tabela revinfo (fazendo as customizações ou não), podemos usar o Envers na nossa aplicação. Basta anotar cada Entidade que for auditada com a anotação @Audited do pacote org.hibernate.envers e criar uma tabela de mesmo nome da tabela original adicionando o sufixo “_AUD” (ou “_aud”) dependento do seu padrão, acrescentando dois campos: rev (do tipo integer se não tiver customizado) e revtype (do tipo smalint).

@Entity
@Table(name = "USU_USUARIO")
@Audited
public class Usuario implements Serializable {
...
}

Caso a tabela criada para auditoria seja diferente do nome da tabela da entidade + o sufixo “_AUD”, deve ser informado na classe colocando a anotação @AuditTable, que recebe a propriedade value para informar o nome da tabela a ser usada.   

@AuditTable(value = "USU_AUD")

Pronto, assim o sistema já está sendo auditado.

Nenhum comentário:

Postar um comentário