Audit avec hibernate envers et oracle

Un peu d’histoire

Envers est un module d’hibernate-core depuis la version 3.5 (d’hibernate). Il a été crée dans le but d’historiser toutes (ou presque) les modifications faites aux entités que l’on souhaite auditer. Nous allons voir rapidement comment fonctionne Envers et ce à quoi il faut penser avant de se lancer dans son utilisation avec Oracle.

Activer envers

Ajouter la dépendance, j’ai utilisé maven pour le projet de test donc :

1
2
3
4
5
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>4.3.8.Final</version>
</dependency>

Depuis la version 4 d’hibernate il suffit d’apposer l’annotation @Audited sur l’entité que l’on souhaite historiser.

1
2
3
4
@Entity
@Audited
@Table(name = "DUCK")
public class Duck {

Hibernate va ensuite créer (automatiquement si vous l’avez mis en update, create ou create-drop) une table identique à celle auditée (par défaut _AUD) dans laquelle on va retrouver toutes les colonnes de la tables auditée. Attention si vous êtes en validate, les tables d’audit font parties du schéma à part entière et votre webapp ne démarrera pas.

Comme décrit dans les premières lignes de la doc l’audit se fait grâce aux transactions. Une transaction représentant une révision globale pour toutes les entités modifiées.

Envers inclus également de quoi requêter ses tables de façon plus intelligente que via des criterias classique, la documentation est plutôt bien faite à ce sujet la avec de bons exemples concrets :

https://docs.jboss.org/hibernate/core/4.3/devguide/en-US/html/ch15.html#envers-queries

On peut récupérer ainsi aisément les entités modifiées à une révision donnée ou encore récupérés les révisions où une propriété avait telle valeur.

Limitations du SGBD (Oracle) et données à prendre en compte avant de choisir Envers.

Il faut sérieusement étudier Envers au plus tôt dans un projet car certains paramètres peuvent être pénibles à gérer par la suite. Cela provient en majorité d’un retour d’expérience sur l’utilisation d’Envers pour un projet auquel j’ai participé.

Modifications en masse

Même si ça peut paraître évident les modifications en masse (requêtes HQL ou SQL) ne peuvent pas être auditées. En effet toutes les requêtes HQL sont  traduite en SQL pur et ne passent pas par les listeners d’envers.
Une solution est alors d’utiliser des triggers directement sur la base, c’est radical mais cela fonctionnera dans tous les cas.

Noms des colonnes

Un des gros problème d’envers est que les noms des colonnes auditées ne se basent par sur le “name” de la colonne mais sur le nom de la propriété java.

1
2
3
4
@Column(name =”LONG_NAME”)
public String getThisIsSuchAVeryLongPropertyName(){
return this.thisIsSuchAVeryLongPropertyName;
}

en base nous allons avoir une colonne nommée :

THISISSUCHAVERYLONGPROPERTYNAME

Avec oracle notamment, cela pose de gros problèmes puisque longueur maximale des noms de colonnes et tables est de 30 caractères… Si cela ne concerne que quelques champs on peut renommer la propriété java mais dans mon cas c’était des dizaines de champs avec un nom difficilement renommable qui devaient rester explicite pour la compréhension du code.

Cependant ne perdons pas espoir car j’ai vu que le mois dernier qu’une issue a été résolue concernant ce problème https://hibernate.atlassian.net/browse/HHH-9043, à tester dans la prochaine release 4.3.9, si vous pouvez mettre à jour la version de votre framework.

Noms des tables

Les noms des tables ne peuvent pas dépasser 30 caractères, sachant que grâce à la propriété :

org.hibernate.envers.audit_table_suffix

on peut limiter la taille du suffixe “_AUD” en le remplacant par “_A” par exemple. Même si c’est pas idéal on n’est pas obligé de renommer la ou les tables auditées.

En bonus même les commiteurs se sont fait avoir sur un jeu de test du framework ;) : https://hibernate.atlassian.net/browse/HHH-9150

 

Conclusion

Finalement envers n’a pas été retenu pour auditer les données lors du projet, notamment à cause de ces problèmes techniques et d’autres bug corrigés dans des versions récentes (ex. https://hibernate.atlassian.net/browse/HHH-7246). Nous avons donc utilisés des développements customs, cependant j’ai pu constater lors de l’écriture de cet article qu’envers est encore en mouvement et que les bugs sont corrigés, un bon point pour ce module complet et très simple d’utilisation.

Vous pouvez retrouver mon projet prêt à l’emploi sur github : https://github.com/olester/envers-example

Liens :
https://docs.jboss.org/hibernate/core/4.3/devguide/en-US/html/ch15.html

VN:R_U [1.9.22_1171]
Rating: 0 (from 0 votes)
Share
Ce contenu a été publié dans Java, avec comme mot(s)-clef(s) , , . Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire