Mettez en oeuvre une relation de persistance Many-to-one unidirectionnelle avec hibernate. Créez les fichiers de mappings et le code Java des objets métiers impliqués dans la relation. Rendez cette relation persistante en base de données. Puis récupérez dynamiquement les objets métiers à partir de leur identifiant clé primaire. Comprenez et mettez en pratique le retard au chargement (Lazy loading), disponible par défaut dans hibernate 3. Identifiez les nuances entre les méthodes de chargement session.get() et session.load() . Mettez en pratique l’attibut ‘cascade’. Enfin, rendez l’association bidirectionelle.
Ce tutoriel est extrait de séances pratiques de la formation HIBERNATE dispensée par Objis.
Prérequis, outils et versions
Tutoriel Hibernate N°2 : votre première application hibernate
Liens utiles
+ de 100 tutoriaux java/jee Objis
Tutoriaux HIBERNATE Objis
Objis, spécialiste formation java depuis 2005
Site hibernate (javadoc, faq)
Doc référence Hibernate
Documentation (chap. 10) : working with objects
Objectifs
Mettre en oeuvre un mapping ‘Plusieurs à un’
Comprendre les méthodes ‘session.get’ et ‘session.load’ d’hibernate
Programme
Contexte
Partie 1 : Aspect statique : Fichiers de mapping
Partie 2 : Aspect statique : Classes Java
Partie 3 : Aspect dynamique : Persistance des objets
Partie 4 : Aspect dynamique : Chargement objets avec session.load
Partie 5 : Aspect dynamique : Chargement objets avec session.get()
Partie 6 : Valeur ajoutée d’un proxy
Partie 7 : Cascade
Partie 8 : Rendre l’association bidirectionnelle
Partie 9 : ManyToMany
Partie 10 : ManyToOne façon JPA
Durée
30 min.
Qui sommes-nous ?
Contexte
Considérez le modèle métier suivant :
Vous êtes chargé de modéliser une relation Plusieurs-vers-un entre un objet métier Formation et un objet métier ‘Lieu’.
Plusieurs formations peux se dérouler dans un même lieu.
La relation se veut unidirectionelle : il doit être possible uniquement de retrouver le lieu d’une formation à partir de la connaissance de cette formation.
Partie 1 : Fichiers de mapping
Analysez le contenu du fichier de mapping de Formation (Formation.hbm.xml)
Analysez le fichier de mapping de Lieu
Expliquez
Partie 2 : Classes Java
La classe Formation contiendra un attribut ‘lieu’ qui correspondra à une colonne de clé étrangère dans la table FORMATIONS.
REMARQUE : notez la présence du constructeur sans argument. Il sera indispensable dans les parties suivantes, durant lesquelles vous souhaiterez chargement en mémoire une formation à partir d’une clé primaire.
L’outil de génération de code JAVASSIST (préféré depuis hibernate 3 à l’outil CGLIB) permet par instrumentation de créer des proxy.
Analysez le code de la classe Lieu
Expliquez
Partie 3 : Persistance
Dans cette partie, vous allez rendre persistant les classes Formation, Lieu en conservant leur relation Many-to-one.
Analysez le code suivant
Expliquez ce que fais ce code.
QUESTION : Comment rendre ce code plus robuste ?
Partie 4 : Chargement objets avec session.load()
Dans cette partie, vous allez charger en mémoire les objets Formation et Lieu à partir de leur identifiant clé primaire en base de données.
La méthode utilisée est la méthode session.load(), qui a la particularité de générer un proxy de l’objet. L’avantage est qu’il n’y a pas physiquement de SELECT en base.
Expliquez
Expliquez la valeur Formation_$$javassist_1 de la variable formation, juste après la ligne 56.
Expliquez la valeur Formation_$$javassist_1 de la variable lieu, juste après la ligne 59.
Expliquez la requête sql suivante, générée juste après la ligne 60. Montrez le lien avec la notion de Lazy loading ou Retard au chargement.
Hibernate a attendu le ‘dernier moment’ pour réaliser une requête en base de données. Il a attendu que vous sollicitiez une effectiveent une des propriétés de l’objet.
Sans quoi vous auriez pu récuperer l’id de l’objet lieu sans avoir à faire de select. Particulièrement utile pour naviguer entre des objets/tables sans charger tous les objets intermédiaires en mémoire.
Version JPA de la méthode hibernate load():
En JPA, l’équivalent de session.load() est em.getReference().
INFO : notez que la notion de proxy n’existe pas formellement en JPA
Partie 5 : Chargement objets avec session.get()
La méthode utilisée est la méthode session.get(), qui aura comme impact la génération physiquement d’un SELECT en base.
Expliquez
Expliquez
Version JPA de la méthode hibernate get():
En JPA, l’équivalent de session.get() est em.find().
Partie 6 : valeur ajoutée d’un proxy hibernate et du mode lazy
Analysez le code suivant, dont l’objectif est de rendre persistant une formation dont le lieu n’est connu qu’à travers sa clé primaire.
Analysez le code SQL produit.
Notez qu’il n’y a pas eu de SELECT pour rechercher l’objet lieu ! seul son id nous intéressait.
Remarque : dans certains cas , vous ne souhaiterez pas bénéficier de ce type de comportement appelé retard au chargement (lazyloading). Vous souhaiterez charger certains objets du graphe systématiquement ensemble. Il s’agit de la notion de fetching,
Partie 7 : valeur ajoutée de l’attribut ‘cascade’
Montrez que le code suivant produit une erreur suivante : Exception in thread « main » org.hibernate.TransientObjectException: object references an unsaved transient instance – save the transient instance before flushing: com.objis.demohibernate.complexe.Lieu
Montrez que l’utilisation de l’attribut ‘cascade’ permet de gérer cette erreur. Paramétrez le fichier de mapping de la classe Formation pour gérer ce problème.
En particulier, expliquez le mapping suivant :
quelle différence entre cascade=all et cascade=save-update ? Expliquez.
Que signifie cascade=all-delete-orphan ?
Partie 8 : rendre l’association bidirectionelle
Modifiez le code et le mapping de la classe Lieu afin de rendre l’association bidirectionnelle.
Expliquez
Expliquez
Corrigé:
Hib-TP-4-many-to-one-Correction
Partie 9 : Association Many-to-many
Analysez le projet eclipse suivant :
Hib-TP-4-many-to-many-Correction
Avant de lancer le test unitaire lancer les commande SQL suivantes:
drop table FORMATIONS;
drop table LIEUX;
Après le test unitaire exécuté lancer la commande suivante:
select * from RFORMATION_RLIEU
Partie 10 : Equivalent JPA du ManyToOne
QUESTION : qu’est ce que JPA ?
QUESTION : quelle différence entre JPA et HIBERNATE ?
Validez que vous avez bien réalisé le tutoriel ‘Votre première application JPA’
Téléchargez et Analysez le projet suivant :
En particulier, analysez le code de l’entité JPA
Ainsi que le code de la classe principale
et du fichier de mapping persistence.xml
Expliquez.
Conclusion
Dans ce tutoriel, vous avez mis en œuvre une relation Many-to-one avec Hibernate. Vous savez comment rendre persistant une une relation Many-to-one. Vous savez également comment charger des Objets métiers impliqués dans une relation Many-to-one à partir de leur identifiant clé primaire.
Vous avez identifié les nuances de chargement via méthode load() et méthode get(). En particuliers, vous avez compris la valeur ajoutée du Lazy loading (retard du chargement).
Vous avez compris la valeur ajoutée de l’attribut cascade dans une relation d’association.
Enfin, vous avez identifié une maneoeuvre permettant d’assurer la bidirectionnalité de la relation, en particulier grace à l’attribut ‘inverse’