[RESOLVIDO] Envers - redefinindo nomes de campos das tabelas _AUD

Olá a tod@s!

Estou com um problema que não sei ainda a solução, que é o seguinte:

Tenho uma tabela TABELA, com os seguintes campos:

TABELA {
    ID,
    CODIGO
    NOME
    EMAIL
}

Naturalmente, ao utilizar o Envers default, sem maiores configurações, tenho a seguinte tabela correspondente de auditoria:

TABELA_AUD {
    REV
    REVTYPE
    ID
    CODIGO
    NOME
    EMAIL 
}

O meu problema está nos nomes dos campos da tabela de auditoria. A equipe de AD, por algum motivo que ainda não compreendo, redefiniu os nomes que devem ser utilizados nessa tabela, e a definiram assim:

XPTO {
    XPREV
    XPID
    XPCODE
    XPNAME
    XPMAIL 
}

A redefinição do nome da tabela de auditoria está ok, consegui encontrar o lugar. O meu problema está nos nomes dos campos. Preciso, agora, informar ao Envers que, ao invés de usar os mesmos nomes de campos da tabela que será auditada (ID, CODIGO, NOME, EMAIL), ele deve utilizar os nomes redefinidos (XPREV, XPID, XPCODE, XPNAME, XPMAIL)

Até agora não encontrei nenhuma solução, estou há quase 2 dias tentando achar alguém que passou por isso para ver se consigo achar alguma luz no fim do túnel.

Desde já agradeço pela atenção de todos!!!

Obrigado!
Rodrigo

Rodrigo,

Não sei se isso será possível, tive um problema parecido com esse, mas não consegui sucesso. Se existisse um @AuditedFieldName ou algo do tipo ajudaria muito.

Olá rfsilva,

O que pode ser configurado no Envers é utilizar um prefixo (o padrão é não ter) e/ou um sufixo (que por padrão é _AUD) com as propriedades org.hibernate.envers.audit_table_prefix e org.hibernate.envers.audit_table_suffix, e isso é o máximo que pode ser feito.

Quanto às colunas, é possível alterar o nome das colunas REV e REVTYPE através das propriedades org.hibernate.envers.revision_field_name e org.hibernate.envers.revision_type_field_name. E novamente, só é possível isso.

Motivo das configurações serem limitadas: Exceto o prefixo/sufixo da tabela e das colunas REV e REVTYPE (que são criadas e gerenciadas pelo próprio Envers), todos os outros nome são ligados à tabela auditada e que por sua vez o Envers utiliza Reflection para poder preencher a tabela de auditoria. Por isso, não há como fazer essas alterações.

Maiores informações sobre a configuração do Envers você pode encontrar em:

http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch15.html#d5e3937

[quote=rimolive]Olá rfsilva,

O que pode ser configurado no Envers é utilizar um prefixo (o padrão é não ter) e/ou um sufixo (que por padrão é _AUD) com as propriedades org.hibernate.envers.audit_table_prefix e org.hibernate.envers.audit_table_suffix, e isso é o máximo que pode ser feito.

Quanto às colunas, é possível alterar o nome das colunas REV e REVTYPE através das propriedades org.hibernate.envers.revision_field_name e org.hibernate.envers.revision_type_field_name. E novamente, só é possível isso.

Motivo das configurações serem limitadas: Exceto o prefixo/sufixo da tabela e das colunas REV e REVTYPE (que são criadas e gerenciadas pelo próprio Envers), todos os outros nome são ligados à tabela auditada e que por sua vez o Envers utiliza Reflection para poder preencher a tabela de auditoria. Por isso, não há como fazer essas alterações.

Maiores informações sobre a configuração do Envers você pode encontrar em:

http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch15.html#d5e3937[/quote]

Oi rimolive,

Vou colocar um exemplo do que eu quero abaixo, para ver se fica claro, e na sequencia explico o que eu acho que o Envers faz.

@Entity
@Table(name = "tb_tabela")
@Audited
@AuditTable(value = "tb_tabela_audit")
public class Tabela {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Integer id;

        @Column(name = "code") //Aqui defino o nome da coluna da tabela "tb_tabela" e a associo ao atributo da classe ("code" para "codigo")
        @Audited(name = "xptocode") //Esse seria o meu desejo, de informar ao envers que o nome da coluna correspondente para auditoria seja redefinido, para "xptocode"
        private String codigo;

        /* getters and setters */
        ...
}

O Envers usa reflection para manipular a classe e seus atributos, e não a tabela e suas colunas. Logo, quando o Hibernate usar o atributo “codigo” da tabela, estará se referindo à coluna “code” da tabela “tb_tabela”, e quando o Envers usar o atributo “codigo” da tabela de auditoria, estará se referindo à coluna “xptocode” da tabela “tb_tabela_audit”. Para mecanismo de reflection no Envers, não há mudança, ou seja, não é (ou não deveria ser) o reflection o causador de um engessamento nessa configuração em particular.

Alguém poderia me ajudar a esclarecer esse ponto, se o Envers faz esse tipo de coisa ou não (e se faz, como fazer)?

Muito obrigado desde já!!!

Rodrigo

É claro que Reflection se trata de classes e atributos, mas Hibernate trata de ORM e ele associa classes e atributos a tabelas e colunas. O Envers aproveita o que a tabela converte de objeto pra relacional e repete o nome das colunas, sem isso a performance do envers seria muito inferior ao que é hoje.

A resposta para sua pergunta sobre o @Audited: Não existe esse parâmetro: http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/envers/Audited.html

Nosso amigo rimolive já disse acima que, infelizmente, não dá pra fazer isso. O Envers não suporta definição dos nomes das colunas que não sejam a REV e REVTYPE, para as outras ele usa o que ficar definido na anotação Column ou pela convenção da JPA.

Você poderia abrir um chamado no Issue Tracking pra ver se o que eles respondem com relação a suportar essa funcionalidade. (Eu concordo com o rimolive sobre a questão da performance. Complexidade demais tem um custo e provavelmente tenha sido esse o motivo dessa funcionalidade ter ficado de fora.)

[quote=Ataxexe]Nosso amigo rimolive já disse acima que, infelizmente, não dá pra fazer isso. O Envers não suporta definição dos nomes das colunas que não sejam a REV e REVTYPE, para as outras ele usa o que ficar definido na anotação Column ou pela convenção da JPA.

Você poderia abrir um chamado no Issue Tracking pra ver se o que eles respondem com relação a suportar essa funcionalidade.[/quote]

Eu já posso até adiantar que a possibilidade de receber um NÃO como resposta é bem grande pelos motivos que já relacionei.

[quote=rimolive][quote=Ataxexe]Nosso amigo rimolive já disse acima que, infelizmente, não dá pra fazer isso. O Envers não suporta definição dos nomes das colunas que não sejam a REV e REVTYPE, para as outras ele usa o que ficar definido na anotação Column ou pela convenção da JPA.

Você poderia abrir um chamado no Issue Tracking pra ver se o que eles respondem com relação a suportar essa funcionalidade.[/quote]

Eu já posso até adiantar que a possibilidade de receber um NÃO como resposta é bem grande pelos motivos que já relacionei.[/quote]

Eu já ia complementar meu post quando vi o seu. Também acho que seja esse o caso.

[quote=Ataxexe][quote=rimolive][quote=Ataxexe]Nosso amigo rimolive já disse acima que, infelizmente, não dá pra fazer isso. O Envers não suporta definição dos nomes das colunas que não sejam a REV e REVTYPE, para as outras ele usa o que ficar definido na anotação Column ou pela convenção da JPA.

Você poderia abrir um chamado no Issue Tracking pra ver se o que eles respondem com relação a suportar essa funcionalidade.[/quote]

Eu já posso até adiantar que a possibilidade de receber um NÃO como resposta é bem grande pelos motivos que já relacionei.[/quote]

Eu já ia complementar meu post quando vi o seu. Também acho que seja esse o caso.[/quote]

Sem contar que a equipe de AD deveria estar preocupada com as Entidades que fazem parte do negócio. Entidades de auditoria são apenas infraestrutura do software, não há relação nenhuma com as regras de negócio.

[quote=rimolive]É claro que Reflection se trata de classes e atributos, mas Hibernate trata de ORM e ele associa classes e atributos a tabelas e colunas. O Envers aproveita o que a tabela converte de objeto pra relacional e repete o nome das colunas, sem isso a performance do envers seria muito inferior ao que é hoje.

A resposta para sua pergunta sobre o @Audited: Não existe esse parâmetro: http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/envers/Audited.html[/quote]

rimolive,

Eu sei que não existe o parâmetro “name” em @Audited. Se não notou, era um “desejo” meu, para exemplificar o que eu queria fazer.

Ataxexe,

O pessoal do Envers deve ter tido preguiça ao decidir não parametrizar esse tipo de coisa. O próprio Envers já é obrigado a tentar ler anotações em classes e atributos de classes. Ler uma a mais ou a menos, ou atributo de anotação a mais ou a menos, não faria qualquer diferença de desempenho. Já fazem isso por default. Já são obrigados a ler tudo da classe via reflection. Meu “desejo”, na minha humilde opinião, em NADA afeta performance. Não é justificativa para não terem feito. Foi preguiça mesmo, infelizmente!

Mas enfim, vamos chorar porque o Envers não faz esse tipo de coisa. No meu cenário, não tenho a flexibilidade para decidir em minha aplicação os nomes de colunas (ou seja, não consigo manter o mesmo nome da coluna para a tabela e a tabela_aud), pois o “pessoal de BD” meteu o bedelho e mudou todos os nomes, e vou ter que jogar o Envers no lixo por isso. Pra mim não serve mais.

Abraços!

Rodrigo

[quote=rimolive][quote=Ataxexe][quote=rimolive][quote=Ataxexe]Nosso amigo rimolive já disse acima que, infelizmente, não dá pra fazer isso. O Envers não suporta definição dos nomes das colunas que não sejam a REV e REVTYPE, para as outras ele usa o que ficar definido na anotação Column ou pela convenção da JPA.

Você poderia abrir um chamado no Issue Tracking pra ver se o que eles respondem com relação a suportar essa funcionalidade.[/quote]

Eu já posso até adiantar que a possibilidade de receber um NÃO como resposta é bem grande pelos motivos que já relacionei.[/quote]

Eu já ia complementar meu post quando vi o seu. Também acho que seja esse o caso.[/quote]

Sem contar que a equipe de AD deveria estar preocupada com as Entidades que fazem parte do negócio. Entidades de auditoria são apenas infraestrutura do software, não há relação nenhuma com as regras de negócio.[/quote]

Com certeza! É muito mais simples deixar o software manter sua própria infraestrutura, afinal, não precisamos nos preocupar se o Envers está dentro dos padrões de nomenclatura XPTObeta2.20 e, sim, se ele está mantendo os históricos corretamente.

Como o caso dele é meio que uma imposição, corre o risco de dizerem “esse Envers não presta, nem dá pra configurar os nomes das colunas e blá blá blá”.

rfsilva,

Talvez com uma única entidade você não notará nenhuma diferença, mas sua aplicação não terá apenas uma entidade, certo? Fora o número de atributos que cada entidade contém.

Tente abrir o JIRA, e discuta com o engenheiros da JBoss sobre o porquê você acha necessário isso. O projeto é da comunidade, discussões serão bem-vindas desde que com bons argumentos, pois dizer que é um desejo seu é no mínimo irrelevante.

Ataxexe,

Corre o risco sim, mas qual framework não corre? :smiley:

Você olhou o fonte do Envers pra ter certeza? O problema não é o Envers ler uma anotação, é gerenciar os metadados a mais, aumentando memória, trazendo um algoritmo a mais pra resolver os nomes de propriedades… tudo isso seria uma extensão no Hibernate cheia de retalhos.

O Envers não acessa o banco de dados, ele é uma casca em torno do Hibernate, por isso ele precisa se limitar a não inserir acoplamento no Hibernate. (Para redefinir as colunas auditadas, ele iria criar outra entidade com mapeamentos parecidos só pra não inserir o acoplamento no Hibernate.)

[quote=rimolive]rfsilva,

Talvez com uma única entidade você não notará nenhuma diferença, mas sua aplicação não terá apenas uma entidade, certo? Fora o número de atributos que cada entidade contém.

Tente abrir o JIRA, e discuta com o engenheiros da JBoss sobre o porquê você acha necessário isso. O projeto é da comunidade, discussões serão bem-vindas desde que com bons argumentos, pois dizer que é um desejo seu é no mínimo irrelevante.

Ataxexe,

Corre o risco sim, mas qual framework não corre? :smiley: [/quote]

rimolive

O Envers JÁ faz por default a varredura em toda a classe (e em todas as classes que são entidades JPA, independente de estarem anotadas como auditoria ou não), mesmo sem necessidade. Não há motivo para acreditar que uma anotação a mais ou um atributo em anotação a mais para ser lido e compreendido vá afetar performance. Talvez o medo em perder performance seja em tentar entender que para auditoria, o nome de coluna é outro, e isso demande implementação e essa implementação demande em consumo de memória e cpu. Aí sim, veria motivo para eventualmente não terem feito. Mas, sinceramente, isso é muito pouco. Ainda estou aguardando a resposta oficial no site do Envers mas meu sentimento é que meu post lá ficará sem resposta.

De qualquer maneira agradeço a vcs pela contribuição na discussão. Infelizmente já estou buscando outras soluções. Talvez eu tenha que reinventar a roda, e escrever meu próprio mecanismo de auditoria, mas isso faz parte dos riscos que estamos correndo ao utilizar frameworks. Um tombo agora pode servir para garantir qualidade lá na frente.

Abraços!

Rodrigo

Você olhou o fonte do Envers pra ter certeza? O problema não é o Envers ler uma anotação, é gerenciar os metadados a mais, aumentando memória, trazendo um algoritmo a mais pra resolver os nomes de propriedades… tudo isso seria uma extensão no Hibernate cheia de retalhos.

O Envers não acessa o banco de dados, ele é uma casca em torno do Hibernate, por isso ele precisa se limitar a não inserir acoplamento no Hibernate. (Para redefinir as colunas auditadas, ele iria criar outra entidade com mapeamentos parecidos só pra não inserir o acoplamento no Hibernate.)[/quote]

Se esse fosse o problema, então nem o próprio nome da tabela de auditoria poderia ser reconfigurado, concorda?

Abraços

rfsilva,

Não é uma questao de fazer uma simples varredura em metadados de classes. Já pensou em quantas tarefas são feitas internamente pelo Hibernate ao fazer um simples Session.save()? Reforço a sugestão do Ataxexe em verificar o código do Envers, pois se você acha preguiça dos desenvolvedores, com certeza você não terá preguiça de fazer, certo

Nem preciso dizer para que é necessário um prefixo/sufixo na tabela de auditoria, né?

[quote=rfsilva][quote=rimolive]rfsilva,

Talvez com uma única entidade você não notará nenhuma diferença, mas sua aplicação não terá apenas uma entidade, certo? Fora o número de atributos que cada entidade contém.

Tente abrir o JIRA, e discuta com o engenheiros da JBoss sobre o porquê você acha necessário isso. O projeto é da comunidade, discussões serão bem-vindas desde que com bons argumentos, pois dizer que é um desejo seu é no mínimo irrelevante.

Ataxexe,

Corre o risco sim, mas qual framework não corre? :smiley: [/quote]

rimolive

O Envers JÁ faz por default a varredura em toda a classe (e em todas as classes que são entidades JPA, independente de estarem anotadas como auditoria ou não), mesmo sem necessidade. Não há motivo para acreditar que uma anotação a mais ou um atributo em anotação a mais para ser lido e compreendido vá afetar performance. Talvez o medo em perder performance seja em tentar entender que para auditoria, o nome de coluna é outro, e isso demande implementação e essa implementação demande em consumo de memória e cpu. Aí sim, veria motivo para eventualmente não terem feito. Mas, sinceramente, isso é muito pouco. Ainda estou aguardando a resposta oficial no site do Envers mas meu sentimento é que meu post lá ficará sem resposta.

De qualquer maneira agradeço a vcs pela contribuição na discussão. Infelizmente já estou buscando outras soluções. Talvez eu tenha que reinventar a roda, e escrever meu próprio mecanismo de auditoria, mas isso faz parte dos riscos que estamos correndo ao utilizar frameworks. Um tombo agora pode servir para garantir qualidade lá na frente.

Abraços!

Rodrigo
[/quote]

Vai por mim, vale muito mais a pena discutir a questão junto aos DBAs. Eu fiz isso uma vez e, quando apresentei os ganhos do Envers, não houve quem levantasse a mão pra questionar se ele se adequava ou não ao padrão de nomenclatura. A solução, no meu caso, foi usar um schema diferente para os dados de auditoria.

Se vocês não são provedores de tecnologia, não vale a pena reinventar a roda em uma solução desse porte (já vi muita empresa quebrar as pernas por causa disso). Pense nisso :wink: (Estou assumindo que são consumidores de tecnologia, desconsidere isso caso contrário)

[quote=rimolive]rfsilva,

Não é uma questao de fazer uma simples varredura em metadados de classes. Já pensou em quantas tarefas são feitas internamente pelo Hibernate ao fazer um simples Session.save()? Reforço a sugestão do Ataxexe em verificar o código do Envers, pois se você acha preguiça dos desenvolvedores, com certeza você não terá preguiça de fazer, certo

Nem preciso dizer para que é necessário um prefixo/sufixo na tabela de auditoria, né?[/quote]

A tabela de auditoria, se vc quiser, pode ter um nome totalmente diferente da tabela a ser auditada, e isso via configuração de anotação (vê lá o @AuditTable). Vc pode bypassar prefixo, sufixo, e colocar PREGUICA no nome da tabela de auditoria se vc quiser, que o Envers aceita.

Eu acho que a preguiça a que me refiro está mais em não haver interesse do Hibernate na evolução do framework Envers, do que em “ah, vou fazer não”. Está mais ligada à estratégia do Hibernate em relação a esse framework doq na dificuldade em si de fazer tal feature. Sinto que o Envers está estagnado nesse momento.

Obrigado!

Rodrigo

[quote=rfsilva][quote=rimolive]rfsilva,

Não é uma questao de fazer uma simples varredura em metadados de classes. Já pensou em quantas tarefas são feitas internamente pelo Hibernate ao fazer um simples Session.save()? Reforço a sugestão do Ataxexe em verificar o código do Envers, pois se você acha preguiça dos desenvolvedores, com certeza você não terá preguiça de fazer, certo

Nem preciso dizer para que é necessário um prefixo/sufixo na tabela de auditoria, né?[/quote]

A tabela de auditoria, se vc quiser, pode ter um nome totalmente diferente da tabela a ser auditada, e isso via configuração de anotação (vê lá o @AuditTable). Vc pode bypassar prefixo, sufixo, e colocar PREGUICA no nome da tabela de auditoria se vc quiser, que o Envers aceita.

Eu acho que a preguiça a que me refiro está mais em não haver interesse do Hibernate na evolução do framework Envers, do que em “ah, vou fazer não”. Está mais ligada à estratégia do Hibernate em relação a esse framework doq na dificuldade em si de fazer tal feature. Sinto que o Envers está estagnado nesse momento.

Obrigado!

Rodrigo

[/quote]

Tá aí uma coisa que eu concordo contigo: O Envers estagnou. Por isso, ele foi adicionado ao Hibernate core e Hibernate Entitymanager e com isso se tornou o Hibernate ORM.

Mas ele estagnou porque eu não conheço muita gente que nem saiba da existência dele (fora a família de projetos JBoss, o próprio Hibernate tem toda uma família de frameworks), e os que conhecem falam mal. Não seria mais fácil estudar e apontar melhorias no framework do que simplesmente dizer que os engenheiros da JBoss são preguiçosos?

[quote=rfsilva][quote=rimolive]rfsilva,

Não é uma questao de fazer uma simples varredura em metadados de classes. Já pensou em quantas tarefas são feitas internamente pelo Hibernate ao fazer um simples Session.save()? Reforço a sugestão do Ataxexe em verificar o código do Envers, pois se você acha preguiça dos desenvolvedores, com certeza você não terá preguiça de fazer, certo

Nem preciso dizer para que é necessário um prefixo/sufixo na tabela de auditoria, né?[/quote]

A tabela de auditoria, se vc quiser, pode ter um nome totalmente diferente da tabela a ser auditada, e isso via configuração de anotação (vê lá o @AuditTable). Vc pode bypassar prefixo, sufixo, e colocar PREGUICA no nome da tabela de auditoria se vc quiser, que o Envers aceita.

Eu acho que a preguiça a que me refiro está mais em não haver interesse do Hibernate na evolução do framework Envers, do que em “ah, vou fazer não”. Está mais ligada à estratégia do Hibernate em relação a esse framework doq na dificuldade em si de fazer tal feature. Sinto que o Envers está estagnado nesse momento.

Obrigado!

Rodrigo

[/quote]

Vamos lá, será meu último post aqui:

Se você não pudesse modificar a tabela de auditoria, elas teriam o mesmo nome, o que seria impossível de acontecer. Como o Envers necessita, obrigatoriamente, de um nome novo para a tabela, ele deixa que você configure também.

Não vou nem comentar sobre a “estagnação” do Envers. Sinta-se à vontade para ignorar o que quiser. Eu, por exemplo, irei ignorar essa thread, pois vejo que não está disposto a pensar diferente, não vou perder tempo aqui.