Auditoria (Envers) utilizando p:dataTable dinâmico

2 respostas
JulianaJolie

Olá pessoal!
Estou com um problema com a minha aplicação... Estou fazendo auditoria de algumas tabelas usando o Envers.

Criei a RevisionEntity:

public class LogRevisaoListener implements RevisionListener {


	@Override
	public void newRevision(Object revisionEntity) {
		LogRevisaoEntidade logRevisaoEntidade = (LogRevisaoEntidade) revisionEntity;

		UsuarioPrincipal usuarioPrincipal = (UsuarioPrincipal) SecurityContextAssociation.getPrincipal();
		if(usuarioPrincipal != null){
			logRevisaoEntidade.setIpMaquina(usuarioPrincipal.getIp());
			logRevisaoEntidade.setNomeMaquina(usuarioPrincipal.getNomeMaquina());
			
			if(usuarioPrincipal.getUsuario() != null){
				logRevisaoEntidade.setCodigoUsuario(usuarioPrincipal.getUsuario().getId());
				logRevisaoEntidade.setNomeUsuario(usuarioPrincipal.getUsuario().getNome());
			}
		}
	}

}

A LogRevisaoEntidade, para salvar informações adicionais sobre as tabelas auditadas (nesse caso o usuário, hora, IP e nome da máquina):

@Entity
@Table(name = "cad_LogRevisaoEntidade")
@RevisionEntity(LogRevisaoListener.class)
public class LogRevisaoEntidade {
	
	@Id
	@GeneratedValue
	@RevisionNumber
	private long id;
	
	@RevisionTimestamp
	@Temporal(TemporalType.TIMESTAMP)
	private Date dataRevisao;
	
	private long codigoUsuario;
	private String nomeUsuario;
	private String ipMaquina;
	private String nomeMaquina;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public Date getDataRevisao() {
		return dataRevisao;
	}
	public void setDataRevisao(Date dataRevisao) {
		this.dataRevisao = dataRevisao;
	}
	public long getCodigoUsuario() {
		return codigoUsuario;
	}
	public void setCodigoUsuario(long codigoUsuario) {
		this.codigoUsuario = codigoUsuario;
	}
	public String getNomeUsuario() {
		return nomeUsuario;
	}
	public void setNomeUsuario(String nomeUsuario) {
		this.nomeUsuario = nomeUsuario;
	}
	public String getIpMaquina() {
		return ipMaquina;
	}
	public void setIpMaquina(String ipMaquina) {
		this.ipMaquina = ipMaquina;
	}
	public String getNomeMaquina() {
		return nomeMaquina;
	}
	public void setNomeMaquina(String nomeMaquina) {
		this.nomeMaquina = nomeMaquina;
	}
}

E agora estou buscando as informações do banco:

public void pesquisarCadastros() throws ClassNotFoundException {

        List<Object> listObject;
		AuditQuery query;
                
        // Cria o auditReader com o EntityManager da aplicação
		auditReader = this.getAuditReader();

		// Query principal, que vai chamar as revisões da classe selecionada
		query = auditReader.createQuery().forRevisionsOfEntity(
				Class.forName(classe), false, true);

		// Se o usuário estiver selecionado, filtra por código do Usuário
		if (usuario != null && usuario.getId() > 0) {
			query.add(AuditEntity.revisionProperty("codigoUsuario").eq(
					usuario.getId()));
		}

		// Se dataInicio e dataFim estiverem preenchidas, pesquisa registro
		// entre as datas
		// .ge - greater equal >=
		// .le - lower equal <=
		if (dataInicio != null && dataFim != null) {
			query.add(AuditEntity.revisionProperty("dataRevisao").between(
					dataInicio, dataFim));
		} else if (dataInicio != null) {
			query.add(AuditEntity.revisionProperty("dataRevisao")
					.ge(dataInicio));
		} else if (dataFim != null) {
			query.add(AuditEntity.revisionProperty("dataRevisao").le(dataFim));
		}

		// Adicionando ordenação por id
		query.addOrder(AuditEntity.property("id").desc());

		listObject = query.getResultList();
 }

Pois bem... Consigo obter informações do banco com o query.getResultList(). O meu problema maior é que o listObject recebe um ArrayList<E>, e cada posição desse list é um Array com 3 Objetos! Os 3 objetos são o retorno da query do Envers: na posição [0] há um objeto da tabela audited que eu referenciei através do atributo "classe", na posição [1] um objeto LogRevisaoEntidade e na posição [2] um objeto RevisionType (que indica ADD, ALT ou REM, se o registro foi de adição, alteração ou exclusão).
Preciso colocar tudo isso em um p:dataTable com colunas dinâmicas, e tentei estudar o exemplo do site [url]http://www.primefaces.org/showcase/ui/datatableDynamicColumns.jsf[/url], mas até agora nada feito.

Alguém pode me ajudar? Já estou a dias tentando resolver isso...

Obrigada!

2 Respostas

JulianaJolie

Pessoal, depois de inúmeras tentativas vi que o Envers não ia atender o que eu precisava.
A solução aqui no meu trabalho foi criar uma trigger no banco de dados para as tabelas audited. Quando um registro for criado na audited a trigger vai salvar qual era o valor anterior do campo e o valor atual, além de informações referentes ao banco, tabela, servidor, etc. Essa tabela vai auxiliar a tabela LogRevisaoEntidade.
Acredito que vá funcionar! :smiley:

Não sei se devo marcar o post como [RESOLVIDO], porque o que fizemos aqui foi tentar de outra forma…

ffcdf

Sei que o tópico é antigo, mas como o trecho de código da JulianaJolie foi muito útil para mim, gostaria de deixar aqui a solução para o problema dela e também para outros que tenham a mesma dúvida.

<p:dataTable value="#{minhaListaDeObjectArray}" id="tabela" var="aud"
	paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} {Exporters}"
	paginator="true" rows="10" rowsPerPageTemplate="10,50,100" paginatorPosition="bottom"
	emptyMessage="Nenhum registro">			
			
	<p:columns value="#{minhaListaStringComNomeDasColunas}" var="columnName" columnIndexVar="i" sortBy="#{aud[i]}" filterBy="#{aud[i]}">
	        <f:facet name="header">
	        	<h:outputText value="#{columnName}"/>
	        </f:facet>
	        <h:outputText value="#{aud[i]}"/>  
	</p:columns>
</p:dataTable>

Obs: Para que o código acima funcione, altere no código da JulianaJolie, o método pesquisarCadastros de void para List<Object[]>. Em seguida também altere o tipo do objeto listObject de List para List<Object[]>. Por fim adicione ao final do método a linha: return listObject;

Criado 29 de maio de 2013
Ultima resposta 9 de jun. de 2015
Respostas 2
Participantes 2