Tag :Hibernate Envers

Hibernons avec Emmanuel Bernard

@emmanuelbernardLe 22 et 23 juin prochains, deux soirées autour d’Hibernate sont proposées respectivement par l’Alpes JUG et le Lyon JUG. Le speaker n’est autre qu’Emmanuel Bernard, un membre de l’équipe Hibernate depuis 2003.
Emmanuel a plusieurs casquettes : il est tout d’abord architecte plate-forme données chez JBoss, membre de l’expert group JPA 2.0 et spec lead de Bean Validation. Emmanuel a dirigé l’implémentation JPA d’Hibernate. Il a fondé et dirige Hibernate Search, Hibernate Validator et le petit nouveau Hibernate OGM. Il intervient régulièrement dans diverses conférences et JUGs, dont JavaOne, JBoss World, Devoxx et est le co-auteur d‘Hibernate Search in Action publié par Manning. Il est aussi le fondateur et co-hôte de deux podcasts: Les Cast Codeurs (français) et JBoss Community Asylum (anglais).
Emmanuel présentera deux sessions aux JUGs. La première sera sur Hibernate OGM. PaaS (Plate-forme as a Service), Cloud, élasticité. Ces mots font le buzz ces temps-ci. Mais le vrai challenge c’est comment et où stocker vos données. Dans un data grid pour bénéficier de la scalabilité? Via une API propriétaire? Est-ce que l’on pourrait utiliser une API familière? L’objectif d’Hibernate OGM est d’explorer comment réutiliser Java Persistence et son API familière pour persister les entités dans une base de données non relationnelle.
Hibernate a bien évolué depuis ses débuts. Il n’est plus un simple ORM mais plutôt un ensemble de projets qui tournent autour du modèle métier. La deuxième session d’Emmanuel sera focalisée sur les différents projets Hibernate comme Hibernate Validator, Hibernate Search ou
Hibernate Envers.

Cet interview a été préparé conjointement par Agnès CREPET et Cédric EXBRAYAT, deux membres de la team du Lyon JUG.

Agnès & Cédric: Lors de la prochaine session du Lyon JUG, tu vas nous parler d’Hibernate OGM, qui permet de disposer d’une implémentation JPA (chouette on est pas perdus, on connait!!!) dans le monde des datagrids NoSQL. Sous quelles impulsions est né ce projet? Quelle est sa maturité à ce jour?
Emmanuel: Le besoin initial est venu d’Infinispan. Les utilisateurs d’Infinispan demandaient une API de plus haut niveau qui leur permettrait de manipuler des objets à la JPA. On a hésité entre la réécriture de zéro ou l’adaptation du moteur Hibernate Core. J’étais de l’avis qu’Hibernate Core ne pouvait pas être adapté pour fonctionner sur les modèles non relationnels. Et pour prouver que j’avais raison, j’ai commencé le prototypage de ce qui est maintenant Hibernate OGM. Évidemment, j’avais tort :)
En travaillant sur le projet et sur la déshydratation des grappes d’objets on a réalisé qu’Hibernate OGM pouvait en principe travailler sur d’autres moteurs NoSQL qu’Infinispan et on a décidé d’élargir le scope tout en gardant Infinispan en implémentation de référence.
Au même moment, nos travaux sur Hibernate Search, sur Lucene et le stockage de ses indexes dans Infinispan nous a convaincu que l’on pouvait écrire un moteur de recherche dont les indexes étaient stockés dans Infinispan.
Ces deux conditions ont permis de résoudre le problème de persistance des entités et le problème de requêtage d’entités.
Hibernate OGM est en release Alpha. Donc à ne pas utiliser pour stocker les comptes bancaires de vos clients.
Le moteur de persistance est, je pense, relativement stable mais l’on discute encore de la meilleure façon de stocker les données (lisibilité vs taille etc). Je pense que l’on va encore travailler sur ces points donc des évolutions seront à prévoir. Si vos données sont de type court terme (ie. à ne pas relire entre chaque montée de version d’Hibernate OGM), pas de soucis.
Pour ce qui est du moteur JP-QL, il n’est pas encore là. Cependant, si vous utilisez Hibernate Search et ses requêtes full-text, vous avez quelque chose de stable.

Agnès & Cédric: Puis-je utiliser Hibernate OGM avec d’autres solutions NoSQL que Infinispan?
Emmanuel: Pas encore. Mais cela fait partie de nos objectifs.
On a travaillé récemment sur l’abstraction du contrat entre Hibernate OGM et Infinispan. Tout n’est pas fini mais je pense que le contrat est en bonne voie et sera capable d’abstraire correctement l’interaction avec des NoSQL clef/valeur d’ici peu. Les gens d’EhCache ont travaillé sur un prototype ce qui nous a aidé à clarifier le contrat.
Les NoSQL de type Document sont les prochains en ligne de mire parce que leur structure est très similaire. Ensuite viendra les NoSQL Column et peut-être les NoSQL Graph.
La partie difficile est de bien gérer les différences entre les opérations primitives et les différences d’isolation transactionnelle (au sens large) entre les moteurs. C’est pour cela que l’on compte beaucoup sur les utilisateurs et la communauté de chaque produit NoSQL pour nous aider dans cette tâche. Idéalement, un expert Cassandra viendra contribuer sur le dialect Cassandra et ainsi de suite.

Agnès & Cédric: On parlait d’impedance mismatch lorsque l’on présentait la problématique du mapping objet/relationnel, pour faire référence aux problèmes rencontrés lorsque l’on voulait faire parler le monde objet de nos applications et le monde des bases de données relationnelles. Mais aujourd’hui comment requêter en JP-QL “au dessus d’une technologie qui ne supporte pas la notion de requête (clé/valeur)”?
Emmanuel: Bonne question. Il y a plusieurs réponses selon ce que la technologie sous-jacente offre. Notre approche (en tous cas initialement) est d’indexer les objets en utilisant Hibernate Search. A chaque fois qu’un objet est créé, modifié ou supprimé, Hibernate Search est au courant et met à jour l’index Lucene correspondant. Cette techno fonctionne et est éprouvée. D’autre part on sait stocker l’index Lucene dans Infinispan (ce qui offre une visibilité des changements immédiate et une distribution de l’index).

Donc la clé et ce sur quoi on travaille aujourd’hui est de convertir une requête JP-QL en requête Hibernate Search / Lucene.
Pour donner un exemple, voici deux requêtes JP-QL converties :
select a from Animal a where a.size > 20
animalQueryBuilder
.range().onField(“size”).above(20).excludeLimit()
.createQuery();

select u from Order o join o.user u where o.price > 100 and u.city = “Paris”
orderQB.bool()
.must(
orderQB.range().onField(“price”)
.above(100).excludeLimit().createQuery() )
.must(
orderQB.keyword(“user.city”).matching(“Paris”)
.createQuery() )
.createQuery();

(c’est l’API de requêtage d’Hibernate Search que l’on voit en action ici)

A noter que la requête n’est qu’un des mismatchs, on peut citer rapidement:
– comment stocker / (dés)hydrater les entités
– comment stocker la notion d’association
– comment éviter le trop grand nombre de lookups de clés (problème équivalent au fameux n+1 selects SQL)
– comment assurer la pérennité des données en cas de changement de structure des objets

Agnès & Cédric: Peut-on comparer Hibernate OGM et Spring Data?
Emmanuel: Il y en a qui ont essayé, ils ont eu des problèmes ;)
Disclaimer: je ne connais pas Spring Data par coeur, j’ai autre chose à faire que d’analyser du matin au soir ce que font des concurrents potentiels. Donc si je dis des bêtises sur ce qu’est Spring Data ne m’en voulez pas.
Spring Data et Hibernate OGM tentent de simplifier l’utilisation des outils NoSQL. Mais je crois qu’à part ça, le niveau de comparaison n’est pas le bon.
Spring Data est un porte-feuille de technologies centrées autour de la donnée. Si on devait comparer, il faudrait regarder du côté de JBoss un bon paquet de projets. Pour en citer quelques uns:
– Hibernate Core
– Hibernate Envers
– Hibernate Search
– Hibernate OGM
– Seam Persistence
– Seam EntityHome framework
– Teiid (fédération de bases de données)
– JBoss Transaction
– Modeshape
– Infinispan
– JCloud (pas JBoss mais un projet intéressant)
– etc

C’est une bonne idée d’avoir regroupé ces technos sous un même portail. J’espère qu’on fera la même chose du côté JBoss: c’est beaucoup plus simple pour les utilisateurs de s’y retrouver.
Cela dit, certains objectifs de Spring Data se retrouvent dans Hibernate OGM notamment via les sous projets Spring Data-MongoDB, Spring Data-JPA, Spring Data key / value. La philosophie n’est pas la même par contre.
Les projets Spring Data encapsulent les APIs des différents datastore dans des template et autre abstractions pour simplifier un peu la vie. Donc vous devez apprendre leurs APIs. Dans l’ensemble je dirais que c’est un énorme helper framework, spécifique à chaque techno qui vous simplifie la vie sans nécessairement masquer la techno en dessous.
Hibernate OGM expose l’API et la sémantique JPA, c’est un moteur JPA dans le sens pur du terme. On pourrait en théorie passer le TCK avec. Du coup, on est plus dans un modèle de programmation proposé et connu qui est JPA et qui est appliqué au datastore que vous voulez utiliser. Hibernate OGM pense aux données sur une période longue, disons 10 ans avec dans l’idée que votre modèle métier va évoluer, voire que vous allez vouloir utiliser vos données sur d’autre plateformes (Ruby, .net etc). Spring Data ne m’a pas donné cette impression, il y a généralement un mapping 1-1 entre un objet et sa représentation en base (ou alors, on se tape le mapping à la main). Pareil, JPA est relativement expressif pour ce qui est relation entre objets y compris circulaire, je n’ai pas vu beaucoup d’options côté Spring Data.
Mais on va tous dans la même direction, simplifier l’utilisation des outils NoSQL et c’est une bonne chose. Il y a deux choses que j’aime particulièrement dans Spring Data:
– leur abstraction de requêtage pour les requêtes relativement simple est très sympa
– l’idée de pouvoir dénormaliser une entité entre plusieurs datastores disparates (je n’ai pas vu d’info dans la doc mais j’ai vu une présentation qui parlait de cette fonctionnalité): je ne suis pas encore 100% convaincu que cela soit utile en pratique mais l’idée est intéressante et c’est quelque chose qu’Hibernate OGM pourra implémenter je pense dans le futur.

Agnès & Cédric: Quel temps peux tu accorder au développement de projets comme Hibernate OGM ? As tu le temps de tester des produits équivalents ou de travailler avec des bases NoSQL ?
Emmanuel: Chez JBoss, on est maître de son temps (et esclave de son travail :) ). Chaque équipe est un peu une mini entreprise qui choisit ses priorités. Par exemple, je fais le choix d’aller à une conférence ou de répondre à une interview et c’est du temps en moins pour développer.
Selon les besoins du moment et les cycles de produits, j’ai du temps pour expérimenter et essayer de nouvelles idées. Par exemple, le premier commit d’Hibernate OGM date de juillet dernier et j’y ai travaillé à temps très partiel pendant la plupart de l’année avant de donner un coup de boost. Le vrai risque c’est de gérer trop de projets en parallèle et donc de ne pas assez les faire avancer individuellement.
Mais bon, il y a pire comme boulot :)

Agnès & Cédric: As tu participé au développement de Ceylon ? Utilises tu d’autres langages tournant sur la VM ? Scala, Groovy, Clojure ? Que penses tu que Ceylon puisses apporter à notre plateforme ?
Emmanuel:
Oui j’ai participé au design de Ceylon et au développement du type checker et de l’infrastructure du projet, là encore à temps partiel malheureusement. C’est assez fascinant de pouvoir partir de zéro et de faire peu de compromis. Personnellement je travaille principalement en Java même si j’ai bossé un peu en Groovy dans le passé. Je me tiens malgré tout au courant de ce qui se passe dans les autres langages (de la JVM ou pas).
Si j’avais à résumer, Ceylon a quatre avantages clés:
– lisibilité
– un système de type très expressif (l’API de réflexion est entièrement type-safe par exemple)
– capacité à décrire dans le langage lui-même des structures hiérarchiques comme des interfaces utilisateur ou des structures qui seraient décrites en XML (et ceci de manière fortement typé)
– de nouvelles API modernes
La règle d’or de Ceylon est que le langage doit être lisible et compréhensible. Quelqu’un qui ne connaît pas Ceylon devrait pouvoir comprendre ce que fait un bout de code. Pour réussir cela, on essaie de garder le langage extrêmement régulier (Ceylon est bien plus régulier que Java par exemple), de limiter les options et de retirer des fonctionnalités si cela rend le langage trop complexe. C’est très frustrant! Récemment, Gavin a supprimé ce qui était probablement ma fonctionnalité préférée: elle pouvait être dangereuse dans certaines situations et 95% des cas d’utilisation sont supportés autrement (moyennant des aménagements dans d’autres fonctionnalités).
Un kit de développement nouveau (API) est un gros défis mais si on se débrouille bien, je pense que ça sera un point clé du succès de Ceylon. Aucun langage n’a vraiment percé sans de bonnes APIs.

Merci Emmanuel!

Les inscriptions pour la session d’Emmanuel au Lyon JUG le 23 juin sont ouvertes! Rendez-vous sur le site du Lyon JUG.
Vous pouvez également assister à sa session à Grenoble, organisée le 22 juin par l’Alpes JUG

JUG Summer Camp – Quoi de neuf dans Hibernate : une perspective de JPA


Quoi de neuf dans Hibernate : une perspective de JPA– Emmanuel Bernard (présentation)
par Audrey Neveu

Emmanuel Bernard nous a présenté les évolutions de JPA 2.0 et les nouveautés à venir d’Hibernate, petit tour d’horizon …

NB : la présentation étant riche en code, plutôt que de recopier tous les exemples proposés par celle ci, nous vous proposons de la télécharger en cliquant sur le lien présentation dans le titre de l’article, chaque partie de l’article citant la/les slide(s) concernée(s) lorsqu’il y a lieu.

Côté ORM :

Standardisation des annotations spécifiques du mapping JPA 2.0 (support des map, list avec index etc …) et création de l’API de critère sont au menu.

Voici certaines des nouveautés d’Hibernate 3.5.x, hors implémentation de JPA 2.0, mentionnées par Emmanuel.

Le Foreign generator :
L’annotation @MapsId est utilisée pour dans les relations @ManyToOne et @OneToOne. Elle permet de mapper la relation avec une clé primaire ou encore une clé composite. (slide 5)

Le Partial Generator :
L’utilisateur a désormais la possibilité de créer son propre générateur d’id en définissant, par l’intermédiaire de deux annotations, les propriétés qui doivent être utilisées  :

  • @GeneratedValue(generator=”inventory”) permet de donner le nom du générateur qui doit être utilisé pour créer l’id de cet objet,
  • @GenericGenerator(name=”inventory”, strategy=”uuid2″) permet de donner sa définition.

Néanmoins, comme son nom l’indique, le partial generator ne génère qu’une parcelle de l’id seulement, il est donc plutôt recommandé pour mapper un modèle existant. (slides 6 et 7)

Les propriétés Read / Write sur une définition de Column :
Cette propriété n’est pas disponible en annotation mais elle permet d’insérer les fonctions de décryptage et d’encryptage à la lecture et l’écriture en base de données. (slide 8)

Les fetch profile multiples :
Un fetch profile permet de définir la stratégie de chargement des relations (Lazy, Eager, etc …) définies pour une entité qu’on remonte par une requête. La stratégie de chargement définie directement sur les relations s’applique par défaut , mais l’utilisateur peut la surcharger par celle définie par un profile qu’il peut activer ou désactiver au runtime. (slide 10)

L’API Criteria

Criteria est une façon de construire les requêtes purement orientée objet : elle est type-safe, fortement typée et peut même générer un méta-modèle qui décrit le modèle métier, grâce à l’outil annotation processor. L’annotation processor va ainsi, via un plugin Maven / script ANT / votre EDI, générer le méta-modèle à partir de votre entité annotée. Ce méta-modèle va se présenter sous la forme d’une classe qui aura le même nom que votre classe de départ, suivie de _ . Chaque attribut monovalué sera par exemple déclaré via un SingularAttribute qui reprendra le nom de la classe de référence et le type de la variable. (slide 12)

Construire une requête avec CriteriaBuilder

On démarre un entity manager avant d’utiliser la classe CriteriaBuilder qui est une aide à la construction des requêtes. Cette classe contient toutes les fonctions utiles pour la création d’une requête telles que from et fetch (slide 14). Elle permet également de récupérer un CriteriaQuery typé, l’objet requête passé au CriteriaBuilder étant déjà typé, inutile de re-préciser le type de l’objet. Criteria Builder est une véritable boîte à outils qui va permettre d’effectuer des jointures, des clauses where avec des alias, et de faire des fonctions plus avancées dans les requêtes telles que des greaterThan. (slide 15), having et count (slide 16), etc … Il est également possible de faire des sous-requêtes (requête imbriquée dans une autre requête) et des requêtes de type unique / distinct. (slide 17)

Quand utiliser JP-QL Query ou Criteria ?

Criteria étant plus naturel pour les gens habitués à écrire des requêtes objet, elle est particulièrement indiquée pour obtenir des requêtes complètes ou plus complexes.

Lock Mode

Le lock mode permet d’appliquer un lock au niveau de la base de données pour éviter un certain nombre de phénomènes lors de l’accès concurrent aux données, si on ne veut pas lire ce qui n’a pas encore été commité par exemple (prevents from dirty read).

On distingue différents types de locks, parmi lesquels :

  • le lock optimiste : avec un numéro de version incrémentale, à vérifier avant la transaction. Seule la modification n’est pas accessible pendant la transaction ;
  • le lock pessimiste ou read/write : avec un numéro de version utilisé pour vérifier les problèmes potentiels. La lecture et la modification ne sont pas accessibles pendant la transaction.

Cache de second niveau et Infinispan

Le nouveau cache de second niveau va permettre d’accéder à un degré de configuration plus fin (par type d’entité, par type de collection ou par requête) et à un tuning plus important (éviction, niveaux de cohérence).

Le cache de données JBoss Infinispan permet de copier une information partiellement sur un ou plusieurs noeuds. Plus léger que le JBoss Cache, il permet d’obtenir de meilleures performances pour l’accès aux données que ce soit en local ou lorsqu’elles sont distribuées. La configuration est embarquée dans la configuration xml traditionnelle (persistence.xml ou hibernate.cfg.xml) pour plus de simplicité.

Changement de packaging

Le core en version 3.5 contient actuellement les modules Annotations, Entity Manager et Envers en plus du core bien entendu. La 3.6, quant à elle, exclut annotation, cette api n’étant supportée que par le JDK 1.5 et au dessus.

Hibernate Search

Hibernate Search est le désormais célèbre module qui permet de faire de la recherche full text à la google et de la recherche rapide avec plusieurs mots, le tout avec de l’approximation et un tri par pertinence. C’est cette partie qui fait le lien entre la recherche Hibernate et le projet Apache Lucene qui est un moteur de recherche full text.

Le mantra d’Hibernate Search est simple : «you focus on the search, we focus on the infra», en bref simplicité d’utilisation :

  • Lucene ne met pas à jour les index lui même, HibernateSearch oui et il applique les modifications à la base de données.
  • Lucene parle chaine de caractère, HibernateSearch convertit en objet.

De plus il propose un modèle de programmation unifié en gérant Criteria, HQL, SQL et full text et une indexation massive via l’API fullTextSession. (slide 25). L’API permet quand à elle de définir le méta modèle en lieu et place de ce que permettent les annotations placées directement sur un objet (slide 26).

Deux approches à Lucene sont possible : la version text (champs : champs) ou la version programmatique : range(), onField(), from(), exclude(), to() … depuis la version 3.3.0. (slide 27)

Hibernate Envers

Grâce à l’Entity Versionning on stocke tout ce qui se passe en base de données, sans toucher au schéma existant. Cette approche est proche de celle du SVN : elle permet de rajouter des révisions sur les commit et de savoir quels champs ont été supprimés, ajoutés, quelles étaient les relations etc ….

En rajoutant simplement l’annotation @Audited sur les entités concernées, on va pouvoir connaître la date et le numéro de révision, la nature de l’opération, ainsi que les informations enregistrées. (slide 30)

Le Lookup permet quant à lui de savoir, pour telle entité, à quelle moment la valeur ‘a’ s’est changée en ‘b’, ce qui peut être particulièrement utile pour les actions en bourse par exemple. Il est ainsi possible de voir l’état d’un ensemble d’entités pour une révision donnée (slide 31) ou de voir tout l’historique d’une instance particulière à travers le temps (slide 32).

Hibernate Validator

Comme son nom l’indique Hibernate Validator est un système validation de données implémentant la spécification BeanValidation et va permettre d’appliquer une validation homogène des données sur chacun des tiers Présentation (ex. JSF, Wicket), persistance (JPA 2.0) et base de données (définition des contraintes).

Il va nous permettre de définir un certain nombre de contraintes sur une propriété, de créer ses propres contraintes, de composer, de grouper en sous éléments (pour valider un sous ensemble de propriétés), etc …

En continuant à utiliser le site, vous acceptez l’utilisation des cookies. Plus d’informations

Les paramètres des cookies sur ce site sont définis sur « accepter les cookies » pour vous offrir la meilleure expérience de navigation possible. Si vous continuez à utiliser ce site sans changer vos paramètres de cookies ou si vous cliquez sur "Accepter" ci-dessous, vous consentez à cela.

Fermer