Tag :Hibernate

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

EclEmma et Hibernate Tools

J’ai découvert récemment deux plugins Eclipse assez pratiques :

  • EclEmma : il permet d’avoir instantanément la couverture de code,
  • Hibernate Tools : il offre plusieurs fonctionnalités qui aident à l’écriture des requêtes en Criteria ou HQL.

EclEmma est un plugin libre pour Eclipse qui se base sur l’outil d’analyse de couverture de code EMMA. Il intègre les fonctionnalités d’EMMA directement dans le workspace d’Eclipse.
Ce plugin s’installe en quelques cliques et ne nécessite pas de configuration particulière. De plus, il est non invasif (il ne rajoute pas des fichiers partout).
Pour l’utiliser, il suffit de lancer les tests unitaires en mode « coverage » (bouton dans Eclipse coverage). À chaque lancement, une session est créée. Celle-ci peut être sauvegardée et importée plus tard.
Les résultats de l’analyse sont les suivants :

  • une vue d’ensemble de la couverture sous forme d’arborescence du code du projet à la méthode,
  • la possibilité d’avoir les résultats par nombre de ligne de code, bloc, méthode, classe …
  • une coloration du code (vert : ligne totalement couverte, jaune : ligne partiellement couverte et rouge : ligne non couverte).

EclEmma offre aussi la possibilité d’exporter les résultats sous forme de rapport dans les formats HTML, XML ou TXT.

Eclipse : EclEmma - vue coverage

Eclipse : EclEmma – vue Coverage

Hibernate Tools est développé par JBoss : c’est une composante de JBoss Tools. Il existe sous forme de plugin pour Eclipse et de tâche pour Ant et fait aussi parti de JBoss Developper Studio.
Le plugin pour Eclipse contient plusieurs fonctionnalités :

  • Mapping Editor : en plus de la coloration et l’auto-complétion que l’on a par défaut dans Eclipse, cet éditeur fournit l’auto-complétion dans les fichiers de configuration Hibernate sur les noms de classes et d’attributs des objets domaines et les noms de tables et de colonnes de la base de données.
  • Console : après configuration, cette vue permet de visualiser le mapping entre les objets domaines et la base de données, d’avoir un éditeur de requête en HQL et en Criteria.
  • Reverse Engineering : c’est la fonctionnalité la plus puissante d’Hibernate Tools. À partir d’une base de données, il est possible de générer les fichiers de mapping, les objets domaines, la couche DAO, la documentation …

La suite de ce post portera uniquement sur la Console Hibernate. Elle correspond à la perspective « Hibernate » dans Eclipse.
Après avoir installé le plugin dans Eclipse, il faut configurer la connexion à la base de données, le fichier de configuration Hibernate et le projet où se trouve les objets domaines.
Attention, si le fichier de configuration Hibernate contient l’élément class-cache, on obtient une exception Hibernate : org.hibernate.HibernateException: Could not instantiate cache implementation. Pour contourner ce problème, j’ai créé un fichier de configuration Hibernate sans les éléments class-cache.
La Console ne prend pas les changements à la volée, en cas de modification des fichiers de mapping ou des objets domaines, il faut penser à recharger la configuration.
La perspective console contient quatre vues principales :

  • la vue configuration,
  • l’éditeur HQL,
  • l’éditeur Criteria,
  • la vue propriétés.

La vue configuration est composé de trois sous parties : configuration (mapping), session factory (objets domaines) et database (base de données). L’utilisateur peut explorer ces trois parties ; on retrouve les attributs/colonnes, ainsi que les types de données. En sélectionnant un élément de la configuration, il est possible d’éditer la classe Java ou le fichier de mapping correspondant ou d’ouvrir l’éditeur de requête HQL/Criteria contenant la requête de sélection de cet élément.

Eclipse : perspective Hibernate

Eclipse : perspective Hibernate

L’éditeur HQL est très pratique pour développer et débugger du HQL :

  • saisie des paramètres dans la vue Query Params,
  • traduction dynamique de la requête en SQL (Hibernate Dynamique SQL Preview),
  • affichage des résultats (Hibernate query Result), ainsi que la possibilité d’explorer les objets dans la vue propriétés.

L’éditeur Criteria offre juste la possibilité d’exécuter les requêtes. Pour les deux éditeurs de requêtes et à chaque édition de requêtes, on obtient le temps d’exécution et le nombre de résultats.

Merci à David de m’avoir fait découvrir ces deux plugins.
Merci à Ellène et Victor pour la relecture.

Devoxx 2010

devoxx10-120x240-blackDevoxx est une conférence européenne indépendante qui porte sur les technologies Java/JVM . Organisée en Belgique, à Anvers, elle nous permettra d’entendre du 15 au 19 novembre 2010 des speakers de haut niveau. Un peu moins de 3000 développeurs venant de plus de 40 pays différents s’y retrouvent chaque année.

Les conférences

Les University Days.

Les 2 premiers jours sont appelés les University Days. On y retrouve principalement des ‘University Talks’, des conférences de 3 heures qui abordent un sujet en profondeur. Il y a à chaque fois plusieurs conférences sur un même créneau horaire. Les sujets sont variés, la plupart sont techniques. Ainsi, on retrouve des sujets :

Chacun peut participer à 2 sessions de 3 heures par jour, une le matin et l’autre en début d’après midi. Ensuite, place aux ‘Tools in action’. Ce sont des petites sessions de 30 minutes qui permettent aux speakers de nous faire découvrir un outil auquel ils ont participé. Les sujets sont variés, d’une présentation de spring developer tools (que j’apprécie énormément au quotidien), à visual VM (outil de monitoring) en passant par Apache Mahout.
Entre 19 et 22h, ont lieu des BOF (Bird-of-a-Feather) qui diffèrent beaucoup de tous les autres types de conférences.
Elles réunissent peu de personnes et sont beaucoup plus informelles. Elles sont généralement menées par un ou deux speakers de manière libre. Parfois, il y a une brève présentation puis des questions, parfois ce sont des discussions ouvertes sur un sujet précis. Actuellement, le planning n’est pas finalisé sur les BOFs.

Les Conference Days

Pour les 3 jours suivants, du mercredi au vendredi, le format diffère. Les conférences  ne sont plus de 3 heures mais d’une heure : cela permet de voir bien plus de sujets différents mais de manière un peu plus superficielle. Les sujets là encore tournent autour des mêmes thèmes dans 5 salles différentes. Les sessions ‘Tools in action’ disparaissent au profit des Quickies, qui durent 15 minutes pendant la pause déjeuner.

Duchess à Devoxx

Les duchess seront présentes toute la semaine à Devoxx et plusieurs nationalités seront présentes (France, Belgique, Hollande …). Le jeudi soir, les Duchess organiseront une BoF pour discuter en petits groupes (6) autour de sujets choisis sur le thème ‘Les femmes dans l’informatique‘.

Ce que j’aime à Devoxx

Pour un prix raisonnable, Devoxx apparait comme un des principaux rendez-vous européen. Les speakers y sont accessibles et l’organisation bien rodée. En une semaine, cela permet d’améliorer fortement sa ‘culture générale Java’, surtout si l’on est débutant. Anvers n’est qu’à deux heures de Paris en Thalys, les hôtels y sont à un prix abordable. Bref, pour un investissement moyen, cela permet vraiment de progresser au niveau technique et de rencontrer énormément de monde, ce qui est toujours un avantage. Certaines SSII l’ont bien compris et y envoient chaque année plusieurs consultants.  Ceux qui n’ont pas une entreprise pour les y envoyer peuvent tout à fait se le permettre au niveau financier. Les conférences sont bien sûr des endroits où l’on apprend beaucoup, mais toutes les discussions ‘off’ pendant la pause déjeuner ou autour d’une bière le soir permettent d’avoir des retours d’expérience très intéressants.

Infos Pratiques

Au niveau de la gestion à proprement parler, pour ceux qui assiste aux University Days, deux possibilités : soit dormir sur place le dimanche soir, soit il est tout à fait possible de prendre l’un des premiers Thalys, de passer à l’hôtel si celui ci est proche de la gare et en ne perdant pas de temps de prendre le tramway pour assister aux premières sessions.
Pour les hôtels, les français semblent se regrouper cette année à deux endroits différents : l’Agora (qui devient à partir d’octobre le ‘all seasons Antwerpen City Center’) et le Park Inn qui sont tous les deux placés juste à côté de la gare. Il vaut mieux éviter de prendre les hôtels qui semblent plus proche de la salle pour deux raisons : ils sont mal desservis en transport en commun et cela veut dire également que vous ferez le chemin seul le soir et le matin.
L’année dernière, le petit déjeuner était compris dans la conférence, tout comme le repas du midi.
Au niveau du train du retour pour le vendredi, beaucoup prennent les thalys de 14h30 ou de 15h30, et certains y restent le week end pour découvrir la Belgique !

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 …

Hibernate un ami qui vous veut du bien ?

Cet article est un retour d’expérience sur la mise en place d’une pagination dans un écran de recherche contenant un filtre composé de deux listes déroulantes. Hibernate fonctionne avec la majorité des SGBD. Toutefois, ceux-ci n’offrent pas tous les mêmes fonctionnalités. Le SQL natif généré par Hibernate sera différent selon les SGBD. Nous verrons en quoi cela peut poser problème.

Ce cas s’appuie sur une application utilisant Hibernate et Sybase ASE 12.5. L’écran à développer, en plus de la pagination, possède un filtre facultatif. La clause where étant dynamique, je décide d’utiliser les Criteria pour écrire ma requête.  Il y a dans le manuel Hibernate une section dédiée à la pagination. Elle vous conseille d’utiliser les méthodes setFirstResult et setMaxResults de l’interface Query en précisant qu’Hibernate sait comment traduire ceci en SQL natif adapté à votre SGBD.

J’implémente ma dao et je filtre le résultat renvoyé :

[[code]]czoyODI6XCJDcml0ZXJpYSBjcml0ID0gc2Vzc2lvbi5jcmVhdGVDcml0ZXJpYShGbHV4LjxzdHJvbmc+PHNwYW4gc3R5bGU9XFxcImNvbHtbJiomXX1vcjogIzgwMDA4MFxcXCI+Y2xhc3M8L3NwYW4+PC9zdHJvbmc+KTsKPHNwYW4gc3R5bGU9XFxcImNvbG9yOiAjMDA4MDAwXFxcIj4vL2Fqb3V0e1smKiZdfSBkZXMgcmVzdHJpY3Rpb25zIOKAkyBmaWx0cmUgdXRpbGlzYXRldXI8L3NwYW4+Ckxpc3QgcmVzdWx0ID0gY3JpdC5zZXRGaXJzdFJ7WyYqJl19ZXN1bHQoZmlyc3RSZXN1bHQpCiAgICAgICAgICAgIC5zZXRNYXhSZXN1bHRzKG5iUm93cykubGlzdCgpO1wiO3tbJiomXX0=[[/code]]

J’écris mon test unitaire, je réalise quelques tests sur ma base de données de test, je « commit ». Voilà, c’est fini !

Quelque temps plus tard, le chef de projet souhaite faire des tests en pré-qualification sur un nombre de lignes conséquent (il est vrai que tester la pagination quand il n’y a qu’une seule page ce n’est pas très drôle). La pagination fonctionne sur les premières pages, mais impossible d’afficher la dernière page sans faire tomber l’application. Le message d’erreur suivant est très explicite :

<10 juin 2010 15 h 20 CEST> <Critical> <Health> <BEA-310003>
<Free memory in the server is 4 122 880 bytes. There is danger of OutOfMemoryError>
[[code]]czoyODI6XCI8c3BhbiBzdHlsZT1cXFwiY29sb3I6ICNmZjAwMDBcXFwiPkV4Y2VwdGlvbiBpbiB0aHJlYWQgXFxcIltBQ1RJVkVdIEV4ZWN1dGV7WyYqJl19VGhyZWFkOiBcXFwnMThcXFwnIGZvciBxdWV1ZTogXFxcJ3dlYmxvZ2ljLmtlcm5lbC4KRGVmYXVsdCAoc2VsZi10dW5pbmcpXFxcJ1xcXCIgamF2YS57WyYqJl19bGFuZy5PdXRPZk1lbW9yeUVycm9yOiBKYXZhIGhlYXAgc3BhY2UKCi4uLgpUaGUgZXhjZXB0aW9uIG1lc3NhZ2UgaXMgLSBKYXZhIHtbJiomXX1oZWFwIHNwYWNlCmphdmEubGFuZy5PdXRPZk1lbW9yeUVycm9yOiBKYXZhIGhlYXAgc3BhY2U8L3NwYW4+XCI7e1smKiZdfQ==[[/code]]

En regardant le code SQL généré par Hibernate, on remarque qu’il n’y a pas de filtre pour la pagination. Malheureusement, Sybase possède moins de fonctionnalités que d’autres SGBD et ne connaît pas les mots clef « LIMIT » ou « ROWID » et de ce fait, le setFirstResult et setMaxResults ne sont pas traduits en SQL natif. Hibernate est donc obligé de tout récupérer dans sa requête et de faire le filtre de pagination côté java. Il charge les objets en mémoire tant qu’il n’a pas les résultats souhaités pour la page demandée. Cela ne pose pas de problème pour les premières pages, mais lorsqu’on veut atteindre la dernière page, la consommation mémoire explose.

Utilisation de la mémoire - schéma de JConsole

Figure 1 – Utilisation de la mémoire – schéma de JConsole

Ainsi, nous ne pouvons pas utiliser l’interface Query dans ce cas. Cette version de Sybase ne supporte pas non plus les sous requêtes ordonnées. La seule solution que nous avons trouvée est de faire la  requête en deux temps : d’abord sur les identifiants, puis récupérer les données  à partir de ceux-ci.

Cette solution peut s’implémenter de deux façons :

  • Solution 1 : récupérer la liste des identifiants filtrées par Hibernate (même code qu’au début, mais en ne retournant que les identifiants) ;
  • Solution 2 : obtenir la liste de tous les identifiants, puis la filtrer en utilisant la méthode subList de l’interface List.

Nous avons testé les deux solutions. En observant l’utilisation de la mémoire, la solution 2 semble plus performante.

img2-solution1

Figure 2 – utilisation de la mémoire pour la solution 1

Utilisation de la mémoire pour la solution 2

Figure 3 – utilisation de la mémoire pour la solution 2

Pour finir, on a une première requête écrite avec les Criteria qui permet de récupérer tous les identifiants en fonction des filtres de l’utilisateur. Puis, on crée une sous-liste pour ne garder que les id correspondant à la page demandée. On fait une dernière requête en HQL pour récupérer les objets.

[[code]]czo3ODI6XCJDcml0ZXJpYSBjcml0ID0gc2Vzc2lvbi5jcmVhdGVDcml0ZXJpYShGbHV4LjxzcGFuIHN0eWxlPVxcXCJjb2xvcjogIzgwMHtbJiomXX0wODBcXFwiPjxzdHJvbmc+Y2xhc3M8L3N0cm9uZz48L3NwYW4+KTsKPHNwYW4gc3R5bGU9XFxcImNvbG9yOiAjMDA4MDAwXFxcIj4vL2Fqb3V0e1smKiZdfSBkZXMgcmVzdHJpY3Rpb25zIOKAkyBmaWx0cmUgdXRpbGlzYXRldXI8L3NwYW4+CgpMaXN0IGxzSWQgPSBjcml0LnNldFByb2plY3R7WyYqJl19aW9uKAogICAgICAgICAgIFByb2plY3Rpb25zLnByb3BlcnR5KDxzcGFuIHN0eWxlPVxcXCJjb2xvcjogIzAwMDBmZlxcXCI+XFxcImlkXFxcIjwve1smKiZdfXNwYW4+KSkubGlzdCgpIDsKCkxpc3QgcmVzdWx0ID0gbnVsbDsKCmlmICggbHNJZCAhPSBudWxsICZhbXA7YW1wOyZhbXA7YW1wOyB7WyYqJl19IGxzSWQuc2l6ZSgpJmFtcDtndDswKSB7Cgk8c3BhbiBzdHlsZT1cXFwiY29sb3I6ICMwMDgwMDBcXFwiPi8vc2kgbGEgbGlzdGUgZFxcXCdpZHtbJiomXX0gZXN0IHZpZGUsIGxhIHJlcXXDqnRlIGhxbCBwbGFudGU8L3NwYW4+CglRdWVyeSBxID0gZ2V0U2Vzc2lvbkZhY3RvcnkoKS5nZXRDe1smKiZdfXVycmVudFNlc3Npb24oKS5nZXROYW1lZFF1ZXJ5KAogICAgICAJCTxzcGFuIHN0eWxlPVxcXCJjb2xvcjogIzAwMDBmZlxcXCI+XFxcImdldEx7WyYqJl19aXN0Rmx1eEJ5SWRzXFxcIjwvc3Bhbj4pLnNldFBhcmFtZXRlckxpc3QoCgkgICAgICA8c3BhbiBzdHlsZT1cXFwiY29sb3I6ICMwMDAwZmZ7WyYqJl19XFxcIj5cXFwiaWRMaXN0XFxcIjwvc3Bhbj4sCgkgICAgICBsc0lkLnN1Ykxpc3QoZmlyc3RSZXN1bHQsCgkgICAgICBsYXN0UmVzdWx0KSk7CntbJiomXX0KCXJlc3VsdCA9IChMaXN0KSBxLmxpc3QoKTsKfVwiO3tbJiomXX0=[[/code]]

A retenir :

Hibernate est votre ami, mais il ne peut pas être plus fort que votre SGBD. Il est donc utile de vérifier le code SQL natif qu’il génère.

Concernant Syabse ASE 12.5, on espère que les versions futures supporteront les fonctions liées à la pagination.

Je remercie David, Ellène et Victor pour la relecture et les conseils sur WordPress.

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