Tag :Hibernate Search

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 …

Paris JUG : La soirée Emmanuel Bernard

La première sortie publique de Duchess France a été le Paris JUG “Emmanuel Bernard” le 9 mars.

Eh oui Emmanuel Bernard est un sujet en soi ! Emmanuel est lead développeur chez JBoss et très impliqué dans la communauté Java open-source. Il a intégré l’équipe Hibernate en 2003, a participé à plusieurs projets d’Hibernate et a été spec leader sur la JSR 303 “Bean Validation”. Ce soir il est venu nous présenter “son bébé”, Hibernate Search, et partager quelques réflexions sur la conception d’API.

Mais avant de commencer la soirée JUG, l’Avant JUG

“L’Avant JUG est un point de rencontre des Duchess avant le JUG. C’est ouvert à toutes les femmes qui vont assister au JUG. Pourquoi ? Parce que si on arrive à 4 on va se dire “tiens il y a des filles aussi”. Si on arrive une par une on disparaît dans la masse de geeks barbus. Bon en fait, la VRAI raison, c’est que c’est l’occasion de piquer un fou rire entre filles, mais ça on ne peut pas le dire à tout le monde.”

Photos Avant JUG 9/3

18h30 : début de l’Avant JUG au Vavin et arrivée des premières Duchess

Le Vavin nous avait préparé un décor cosy dans un coin calme entouré de photos de femmes. Chacune s’est présentée dans un tour de table puis nous avons pris un verre en discutant de nos projets, de notre métier, de nos frameworks préférés. Une moitié n’était jamais venu au JUG, les autres viennent assez régulièrement et profitent de l’Avant JUG pour faire connaissance avec des femmes qu’elles ont croisées de temps à autre au JUG.

19h00 : nous sommes 10, les discussions vont bon train mais il va bientôt être t<emps de partir. Finalement, c’est bien court un Avant JUG.

19h10 : départ pour l’ISEP. Les Duchess sont attendues pour notre première présentation publique en ouverture du JUG à 19h15, la première !

La Présentation des Duchess au JUG

Et voilà, nous sommes devant 200 personnes, à présenter Duchess en ouverture du JUG ! Au passage merci au JUG et à Emmanuel Bernard de nous donner cette opportunité.

Photos presentation JUG 9/3

(Source des photos : http://www.touilleur-express.fr/ et http://twitter.com/Piwai)

La présentation de Duchess France est disponible ici.

Nous sommes bien accueillies par l’assemblée majoritairement masculine qui semble trouver la démarche intéressante. Cette présentation s’est terminée par quelques questions dont voici le contenu en substance :

Question : Pourquoi voulez vous vous rassurer sur nos compétences ?
Réponse : Ce sont souvent les femmes qui se jugent elles mêmes moins compétences. Elles manquent d’assurance sur le plan dans la technique et n’osent pas toujours s’affirmer.

Question : La sous représentation des femmes dans l’informatique est elle commune à tous les pays ?
Réponse : A part quelques exceptions comme en Europe de l’Est et l’Inde la plupart des autres pays sont dans le même cas que la France.

Et maintenant place à Emmanuel Bernard a qui nous avons volé la vedette quelques minutes.

Photo d'Emmanuel Bernard

Première partie de la soirée : Présentation d’Hibernate Search

Tout d’abord qu’est ce que Hibernate Search ?

Hibernate Search est un module d’Hibernate qui permet de faire des recherches plein texte sur des données issues d’une base de données. Plutôt que plutôt que de Hibernate Search a choisi de s’interfacer avec un composant qui fait ça très bien, Lucene. Lucene est un moteur de recherche plein texte puissant fonctionnant sur des documents, généralement des fichiers. Il faut donc créer une couche d’adaptation pour présenter les différents champs de la base de données comme des documents.

Pour débuter Emmanuel Bernard commence par présenter les différentes approches possibles pour la recherche plein texte :

  • la catégorisation des données : on propose à l’utilisateur une liste de catégories dans laquelle il pourra retrouver par exemple ses musiques par genre,
  • la recherche détaillée où l’on propose un écran complet fournissant tous les champs possibles pour effectuer une recherche,
  • la recherche simple avec un champs texte.

La solution la plus appréciée par les utilisateurs est bien évidemment la dernière plus simple à utiliser, comme Google, il suffit de taper des mots clés et on obtient un résultat. Pour implémenter cette solution deux solutions sont envisageables :

  • une requête SQL monstrueuse couvrant tous les cas de recherche,
  • ou Apache Lucene un moteur de recherche puissant écrit en Java.

La solution qui va de soit est bien évidemment la seconde.

Apache Lucene

Lucene est un moteur de recherche plein texte puissant fonctionnant sur des documents, généralement des fichiers. Il faut donc créer une couche d’adaptation pour présenter les différents champs de la base de données comme des documents.

Ce moteur de recherche est décomposé en deux phases :

  • L’indexation permet de découper les phrases en mots. Puis grâce à une série de filtres, il est possible d’épurer les mots en mettant tout en minuscule puis en éliminant les mots “parasite” comme “le” ou “la” par exemple.
  • La recherche en elle même qui va se baser sur les données indexées pour réaliser des recherches rapides et efficaces. Le résultat de la recherche peut être ordonné par pertinence. En effet on peut déterminer qu’un mot clé retrouvé dans un titre de livre est bien plus pertinent que ceux trouvé dans le texte.
    • Recherche approximative basée sur la distance de levenshtein, il permet de retrouver des mots proches de celui que l’on cherche exemple : pour “elepant” il sera possible de retrouver “elephant” par exemple.
    • Recherche des mots de même famille, de synonymes et par phonétique.

Lucene est très puissant mais limité lorsque l’on a une base de données et (éventuellement) Hibernate déjà en place. Et c’est là qu’Hibernate Search entre en jeu. Hibernate Search propose une couche de mapping dans laquelle il est possible de définir l’indexation et les requêtes de façon transparente au travers d’Hibernate.

Pour indexer un livre par exemple :

@Entity
@Indexed
@Analyzer(impl = SimpleAnalyzer.class)
@Table(name = BOOK_TABLE_NAME)
public class Book {

L’annotation Indexed permet d’indiquer à Hibernate que cette classe doit être indexé par Lucene. Pour des valeurs pertinentes comme le numéro ISBN, il est important de ne pas découper la valeur car seul le numéro entier est pertinent :

@Column(name = “isbn”)
@Field(index = Index.UN_TOKENIZED)
public String getIsbn() {
return isbn;
}

Côté recherche, une surcouche d’Hibernate rend les requêtes vers Lucene plus simple. Comme dans une requête Hibernate, on commence par créer une session Hibernate. L’écriture de la recherche peut se faire via une requête Lucene.

La mi-temps

La mi-temps. Il était temps, on a peu faim après toutes ces émotions. Un petit tour pour dire bonjour à tous les gens qu’on connait, une lutte impitoyable pour accéder à un toast et un verre de jus d’orange, et quelques discussions sur Duchess et la place des femmes dans leurs sociétés. La mi-temps est l’occasion pour nous de parler de la création et de l’avenir de JDuchess en petit comité. Les organisateurs et les habitués remarquent que, déjà, plus de femmes que d’habitude assistent à la présentation.

Deuxième partie de la soirée : le design d’API

Emmanuel Bernard est vraiment un speaker passionnant. Dans cette deuxième partie de soirée, il exprime quelques réflexions sur la conception d’API basées sur son expérience de Spec Lead de la JSR 303 (Bean validation) et Project Lead sur Hibernate Search.

Ce ne sont pas que des éléments techniques. Il nous parle des relations pas toujours faciles avec les utilisateurs, de la difficulté de produire des interfaces simples à utiliser, de la difficulté de faire évoluer les APIs. Il revient sur les erreurs qu’il a pu faire et les leçons qu’il en a tirées. La fin est plus technique avec la mise en perspective de différentes techniques d’implémentation et comment elles répondent aux problèmes qu’il vient d’exposer. Et en plus tout cela est fluide et facile à comprendre.

Voici quelques éléments que nous avons retenus.

Une API doit être conçu pour être utilisable par des humains avec un support des IDEs. Idéalement les noms de classes et méthodes doivent être suffisamment clairs pour pouvoir être utilisables même sans documentation.

Sa règle d’or est “Si on ne tombe pas on ne s’améliore pas”. C’est grâce à ses erreurs qu’il a pu remettre son travail en cause et s’améliorer.

Les bonnes pratiques qu’Emmanuel Bernard préconise pour la conception d’API sont :

  • utiliser ses APIs sur de vrais projets, un test n’est pas suffisant,
  • faire en sorte que son API soit compréhensible avec une sémantique simple et intuitive,
  • définir une DSL interne pour faciliter l’utilisation de l’API,
  • rendre les cas d’utilisation principaux très simples à implémenter,
  • lire Effective Java de Joshua Bloch qui fournit plusieurs exemples et bonnes pratiques pour le développement en Java.

La 3ième mi-temps

Cinq d’entre nous étaient à la 3ième mi-temps du JUG. Une occasion supplémentaire de répondre à des questions, de rappeler les contacts pour motiver sa femme ou sa collègue à nous rejoindre et de discuter technique avec d’autres Juggers.

Pour plus de détails sur la soirée “Emmanuel Bernard”, nous vous recommandons quelques articles :

Les commentaires ne marchent pas très bien pour le moment. Nous avons ouvert une discussion ici pour que vous puissiez laisser vos commentaires.

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