RSS Feed

Archives de la catégorie ‘Hibernate’

NormandyJUG – Hibernate vs Cloud Computing & NoSQL

14 December 2011 par SeB Pas de commentaire »

Après plus d’un an et demi de pause forcée, j’ai pu enfin retourner au NormandyJUG !

Cette soirée était consacrée à un seul et unique thème :  l’accès aux données face à la montée en charge. La session était animée par Julien Dubois qui est entre autre l’auteur de Spring par la pratique. Le sujet ou l’intervenant devaient intéresser puisque nous étions une 50aine.

En partant du principe que la scalabilité d’une application Java est limitée par la base de données, la présentation consistait à évaluer les solutions disponibles. En effet, avec le Cloud Computing, il est “facile” d’ajouter des machines pour assurer la montée en charge d’une application mais le point de contention reste le serveur de base de données. Avant d’aller plus loin, il faut rappeler le théorème de CAP qui indique qu’il est impossible de répondre à ces trois contraintes en même temps :

  • Cohérent (Consistent)
  • Disponible (Available)
  • Tolérant aux pannes réseaux (Partition tolerant)
Quelles sont donc les solutions pour la base de données ne soit plus un point de contention ?

Le serveur de base de données

Les éditeurs de base de données proposent par exemple du partitionning de table sur différents disques. Les lectures seront optimisées mais ça ne résout pas réellement le problème d’écriture dans les faits.
Il est également possible de mettre en place des clusters d’applications pour le serveur de base de données. A priori, la montée en charge est possible. Cependant, le cluster doit positionner les locks réseaux qui malheureusement plombent les performances.

Hibernate et le cache

S’il n’est pas possible d’améliorer à volonté la performance de la base de données, nous pourrions être tenté de ne plus systématiquement faire appel à cette dernière. C’est là qu’en en scène le cache de niveau 2 d’Hibernate.
Il faut connaitre le fonctionnement d’Hibernate pour bien utiliser le cache. Il est également possible de mettre en pratique la loi de Zipf pour une utilisation avancée du cache. Néanmoins, très rapidement, vous allez être confronté à des problèmes de désynchronisation de cache. Il faut alors mettre en place une solution de cache distribué. Les solutions commerciales actuelles fonctionnent plutôt bien. En revanche, il faut en même temps investir dans des outils de monitoring afin de prévenir tout phénomène de split brain. Il faut savoir que ces outils peuvent proposer des systèmes de write-behind afin de lancer des batchs asynchrones d’insertion.

NoSQL

Si malgré tous ces efforts, votre application ne tient toujours pas la charge à cause de l’accès au données, il vous reste encore une solution : NoSQL (pour Not only SQL).
Vous vous rappelez du théorème de CAP ? En général, on veut un système cohérent (contrôle d’intégrité, transaction, etc…). Et c’est ce que fait la plupart des serveurs de base de données. NoSQL se concentre sur les deux autres contraintes au détriment de la cohérence. Enfin, pour être plus précis, NoSQL indique qu’il sera cohérent à un moment donné (mais pas forcément tout le temps).
Il existe de nombreuses solutions NoSQL mais ici nous avons vu Cassandra qui serait le plus performant en écriture. En gros, c’est un cluster de données sans maître où chaque données est répliquée sur au moins 3 noeuds. Lorsque l’on interroge un noeud, il répond tout de suite avec les informations dont il dispose. Puis va chercher à se mettre à jour (d’où le à terme sera cohérent). En écriture, la gestion des conflits se fait via une date cliente. C’est donc le dernier arrivé qui l’emporte ! ;-)
Par contre, oubliez schemas, tables, colonnes, SQL et autres ! Vous manipulez un identifiant et des listes de couples clé/valeur. Celà permet de faire des choses assez sympa comme le wide-row. Mais les contre-parties sont :
  • Pas de JPA ni JDBC, il faut tout faire à la main
  • Le modèle est défini dans le métier
Pour information, il existe des drivers pour différents langages. De plus, des projets sont en cours pour faciliter le développement avec par exemple Hibernate OGM (Hibernate) ou Kundera (JPA).
Mais alors quelle solution choisir ?
  • Vous avez besoin de transaction, d’intégrité ? La base de données relationnelle est votre meilleure amie !
  • Les solutions de cache sont vraiment des pistes intéressantes.
  • Vous avez un cloud ? Aujourd’hui, aucune base de données n’est scalable via le cloud. NoSQL pourrait être salvateur.
  • Et si on mixait SGBDR et NoSQL ? :-p
 

Hibernate 3.3

26 August 2008 par SeB Pas de commentaire »

Le projet Hibernate propose une nouvelle version de leur framework de mapping objet-relationnel.

Il y a une dizaine de jours, l’équipe du projet Hibernate a annoncé la sortie de Hibernate Core 3.3.0 GA.

Cette nouvelle version est disponible en téléchargement. Elle n’apporte pas de gros changements puisque l’essentiel des nouveautés concerne le refactoring du projet. Le projet est maintenant construit avec Maven et a été découpé en plusieurs JARs pour réduire les dépendances. De plus, le cache de second niveau a subi quelques améliorations.

 

Dites au revoir aux PermGen space

6 June 2008 par SeB 2 commentaires »

Vous travaillez sous Eclipse ? Vous utilisez un serveur d’applications intégrant Tomcat tel que JOnAS ou JBoss ? Et l’accès aux données est fait via Hibernate (même encapsulé dans la couche EJB3) ? Et pour finir, votre application contient un module web ?

Si vous avez répondu par l’affirmative à la majorité de ces questions, vous devez bien connaitre le message suivant :

PermGen space

Ceci se produit après quelques déploiements à chaud de votre application et provoque le blocage de votre serveur d’application. Après une telle erreur, il ne reste plus qu’à tuer le processus du serveur (le script d’arrêt ne fonctionnant plus) puis à le relancer.

Après avoir investigué sur le sujet, il semble que l’utilisation de bibliothèques externes qui font du chargement dynamique de classe ne soit pas compatible avec le redéploiement car l’URLClassLoader de Tomcat garde des références sur des objets dont les classes ont été chargées dynamiquement lors de l’exécution. Ce qui empêche le garbage collector de faire correctement son travail. ;-)

Or Hibernate utilise la bibliothèque CGLIB pour le chargement dynamique de classe (lazy=false).

Spécifique à la JVM Sun, le PermGen space est une zone mémoire qui contient tout ce qui n’est pas géré par le garbage collector; tout ce qui est relatif au classes (leur structure: méthodes, champs, annotations…), les champs static, les chaines littérales… On spécifie le PermGen space avec les propriétés -XX:PermSize=256m et -XX:MaxPermSize=256m par exemple. Plus on a de classes différentes plus il faut augmenter la taille de cette zone mémoire.

Pour résoudre le problème, enfin pour le repousser devrais-je dire, il est possible d’ajouter le paramètre suivant lors du lancement de votre serveur d’application : -XX:MaxPermSize=256m. La taille étant à définir selon votre utilisation. Par contre, il faut éviter de mettre le paramètre -noclassgc qui empêche le garbage collector de nettoyer l’espace du PermGen.

L’autre solution est d’utiliser la JVM d’IBM ou JRockit de BEA. Mais on ne fait pas de polémique ici. :-P

 

Hibernate – attention aux injections SQL !

21 August 2007 par SeB Pas de commentaire »

J’avoue que le titre de cette note est quelque peu alarmiste. C’est avant tout pour retenir l’attention et marquer les développeurs qui se croient à l’abri de ce genre d’attaque parce qu’ils utilisent Hibernate.

En effet, l’utilisation de ce framework ne vous protège pas forcément des injections SQL comme le rappelle TSS dans son article intitulé “Une légende urbaine à propos d’Hibernate“.

L’auteur explique que la création de requête SQL par concaténation de chaîne de caractères rend possible les attaques par injection de code SQL. Et ce même si vous utilisez Hibernate (contrairement à ce que certaines personnes semblent croire) ! Alors, comment s’en protéger ?

Pour empêcher les injections SQL, il suffit d’utiliser les paramètres nommés lors de la création de requête SQL. Ce genre de pratique est une bonne habitude à avoir.

Donc n’oubliez pas d’utiliser les paramètres SQL plutôt que de construire la requête SQL à la main ! Ce message ne s’adresse pas seulement aux utilisateurs d’Hibernate, ni qu’aux développeurs Java par ailleurs. ;-)

 

Hibernate Tools – empêcher la génération des relations one-to-many

17 August 2006 par SeB Pas de commentaire »

Introduction

Hibernate Tools est très puissant pour générer le code des Java beans et les fichiers de configuration de mapping utilisés par Hibernate. Cependant, le code généré par défaut n’est pas forcément nécessaire. Par exemple, les relations one-to-many sont souvent inutiles.

Par exemple en considérant les tables USER et USER_ROLE et leur Java beans respectifs User et UserRole. La relation many-to-one représentée par la méthode User.getUserState() est utile. Par contre, la relation one-to-many représentée par la méthode UserRole.getUsers() est complètement inutile[1]. Heureusement, les concepteurs de Hibernate Tools ont pensé à nous et nous proposent deux solutions :

  • via le fichier reveng.xml[2]
  • via le reveng. strategy

Solutions

reveng.xml

Ce fichier permet de configurer le comportement de l’outil de génération du mapping à partir de la base de données table par table. Pour empêcher la génération des relations one-to-many, il faut ajouter des sections de la forme :

<table schema="MYSCHEMA" name="USER_ROLE">
      <foreign-key constraint-name="FK_USER_USER_ROLE">
         <many-to-one property="User" exclude="true" />
      </foreign-key>
</table>

reveng. strategy

Cette méthode consiste à implémenter une classe fille de la classe DelegatingReverseEngineeringStrategy[3]. L’implémentation de la méthode ci-dessous permet de ne pas générer de relation one-to-many avec Hibernate Tools :

public boolean excludeForeignKeyAsCollection(String keyname, TableIdentifier fromTable, List fromColumns, TableIdentifier referencedTable, List referencedColumns) {
      return true;
}

Conclusion

La seconde méthode permet d’automatiser le traitement pour l’ensemble des tables dont il est nécessaire de générer le mapping à partir du modèle de la base de données. C’est donc la solution à préférer si l’on souhaite adopter ce comportement par défaut.

Notes

[1] En tout cas pour les utilisations que j’en fait.

[2] Pour le moment, l’éditeur graphique ne permet de configurer cela, il faut le faire à la main.

[3] Cette méthode est très pratique pour automatiser certains comportement qui doivent être commun à toutes les tables, voire toutes les colonnes.

 

Hibernate Tools – Hibernate pour Eclipse & Ant

26 July 2006 par SeB Pas de commentaire »

L’écriture des fichiers de mapping et des Java beans pour Hibernate représente souvent une tâche longue et répétitive. Quelques outils sont sortis pour faciliter cette tâche sans réel succès. Pourtant, Hibernate Tools[1] semble être l’outil qui permet d’augmenter la productivité des développeurs qui s’attelle au travail du mapping entre la base de données et les objets Java avec Hibernate.

Cet outil s’intègre dans Eclipse et est également disponible pour JBoss IDE. Cette solution propose pas moins[2] :

  • d’un éditeur de fichier de mapping
  • d’une console de configuration (connexion aux bases de données, visualisation des relations entre les Java beans, exécution du HQL[3], etc…)
  • ingénierie inverse : génération automatique à partir d’une base de données (fichiers de configuration et de mapping, Java beans, DAO, etc…)
  • des assistants de création
  • des tâches Ant

En résumé, Hibernate Tools permet de gagner énormément de temps lorsqu’il faut générer toute la couche d’accès aux données avec Hibernate. Cependant, il faut lui reconnaître quelques limitations. En effet, lorsque le modèle de la base de données est très proche du modèle objet, il se révèle extrêmement efficace. Malheureusement, le modèle objet n’est pas toujours calqué sur le modèle relationnel. Et dans ce cas Hibernate Tools pêche quelque peu[4].

Même si Hibernate Tools ne répond pas à tous les cas de figures, il a le mérite de bien déblayer le terrain. Puisqu’il est possible de générer une première version d’un mapping simple avec ce dernier, puis de modifier le mapping à la main pour résoudre les cas particuliers.

Un outil à surveiller de très près et surtout à utiliser !

Notes

[1] Il est considéré par certain comme le digne successeur de Middlegen.

[2] Le carnet de route d’Hibernate Tools permet de savoir exactement ce qu’il est possible de faire aujourd’hui et ce qu’il sera possible de faire demain.

[3] Avec une traduction à la volée en SQL !

[4] Même s’il propose de personnaliser l’ingénierie inverse et laisse la possibilité d’implémenter des stratégies d’ingénierie inverse.

 

Hibernate – SQL natif, HQL ou API Criteria ?

17 July 2006 par SeB 9 commentaires »

Introduction

Hibernate propose plusieurs solutions pour réaliser des requêtes en base de données. Lorsque que le développeur doit écrire une requête avec Hibernate, il a trois possibilités :

  • le SQL natif
  • le HQL
  • l’API Criteria (et Example)

Quelle est la meilleure solution pour écrire une requête avec Hibernate ?

Solutions

SQL natif

L’un des objectifs d’Hibernate est de s’éloigner de la base de données[1]. Or, l’utilisation du SQL natif va à l’encontre de cet objectif. De ce point de vue, le SQL natif est à éviter. Néanmoins, l’équipe du projet le conseille seulement de façon exceptionnelle pour des points qui ont besoin d’utiliser une optimisation liée spécifique à la base de données.

HQL

C’est un langage propre à Hibernate qui s’inspire du SQL mais orienté objet. Il est très souple et donne accès à toutes les possibilités d’Hibernate.

API Criteria

C’est une API en Java qui permet de faire la même chose qu’avec le langage HQL. Le code source à écrire est très simple.

Conclusion

Si l’on élimine le SQL natif, il reste le HQL et l’API Criteria qui font la même chose. La différence concerne le développeur :

  • l’écriture de requête sous forme de chaîne de caractères
  • l’appel à une API de requête

Laquelle choisir ?

  • pour obtenir une meilleure souplesse en terme de développement et de maintenance
  • pour atteindre les meilleures performances

Jusqu’à présent j’avais utilisé naïvement simplement Hibernate avec l’API Criteria.

Pourquoi ce choix ? Cette API est très bien faite et la syntaxe des requêtes est validée à la compilation Java. De plus, je suppose que c’est plus rapide puisque qu’il n’y a pas besoin d’analyser de chaîne de caractères pour exécuter la requête. L’analyse du choix de l’implémentation des requêtes mérite d’être poursuivie.

Valère Viandier conseille de mélanger l’utilisation du HQL et de l’API Criteria. Selon lui, toute requête statique doit être implémentée avec le HQL[2]. Et toute requête dynamique doit être codée avec l’API Criteria. Cette dernière permet d’éviter la concaténation de String lors de la construction de la requête.

John Ferguson Smart rejoint le point de vue de V. Viandier dans son article sur l’utilisation de l’API Criteria vis-à-vis de HQL. Puisque selon ce dernier, l’API doit être utilisée pour des requêtes dynamiques. Et inversement HQL doit être utilisé pour des requêtes statiques. Cela permet d’externaliser les requêtes qui pourront être mises en cache, analysées par un administrateur de base de données, etc…

L’utilisation de deux langages de requête peut troubler[3] beaucoup de personnes[4]. Pourtant, pour tirer parti des points forts de chaque langage, il est tout à fait raisonnable d’utiliser à la fois le HQL et l’API Criteria.

Quelqu’un a-t-il un avis sur le sujet ? Ou des retours d’expériences ?

Notes

[1] En terme d’implémentation.

[2] Idéalement dans les fichiers de configuration de mapping hbm.xml.

[3] La maintenance applicative semble moins évidente.

[4] Moi le premier dans un premier temps.

 

Hibernate – table par hiérarchie de classe avec un discriminant de type entier

16 February 2006 par SeB 5 commentaires »

Hibernate permet de faire du mapping d’héritage de classe. Selon la stratégie utilisée, le développeur peut rencontrer quelques difficultés.

lire la suite…

 

Hibernate 3.1

13 December 2005 par SeB Pas de commentaire »

Une nouvelle version majeure du framework de mapping objet-relationnel Hibernate est disponible.

lire la suite…

 

Hibernate – persistance & mapping

21 April 2005 par SeB Pas de commentaire »

La persistance relationnelle dans une application Java résume bien Hibernate.

Hibernate est un framework de mapping objet-relationnel ou de persistance objet des données. En d’autres termes il réalise le mapping entre des objets Java et une base de données relationnelle et assure la persistance.

lire la suite…