Archive pour le tag 'hibernate'

Hibernate - attention aux injections SQL !

21 août 2007

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 SQL">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. ;-)

Mais où est donc l’API de requête pour les EJB3 ?

8 février 2007

Pour rappel, les EJB3 sont le résultat du mariage entre les EJB2 et Hibernate et XDoclet Hibernate Annotation.

Lorsque les développeurs travaillent avec Hibernate, ils prennent vite l’habitude d’utiliser le HQL pour les requêtes statiques et l’API Criteria pour les requêtes dynamiques[1]. Cependant, le passage d’Hibernate aux EJB3 Entities provoque quelques frustrations. En effet, mis à part le JPQL[2] qui est l’équivalent du HQL chez Hibernate, il n’y a aucune API pour générer dynamiquement des requêtes sur les EJB3 Entities ! :-/

Faut-il attendre les EJBs 3.1 ou 4 ? Au moins de quelqu’un nous sorte de son châpeau une petite API Criteria pour les EJB3;-)

 

Notes

[1] Comme expliqué dans SQL natif, HQL ou API Criteria ?">le comparatif SQL, HQL et API Criteria.

[2] Pour lequel il existe un tutorial et une documentation de référence du language.

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

17 août 2006

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 celà, 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 - SQL natif, HQL ou API Criteria ?

17 juillet 2006

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 language 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 language 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. Celà 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 languages de requête peut troubler[3] beaucoup de personnes[4]. Pourtant, pour tirer parti des points forts de chaque language, il est tout à fait résonnable 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.