User Tools

Site Tools


wiki:epims4_1:developer:epcorehibernate

Hibernate

Attention : Si dans les fichiers de mapping (.hbm) on utilise un set pour les collections non ordonnées, on ne peut pas utiliser ces collections dans des 'datatable' (JSF) pour la partie view. ⇒ Utilisation de 'bag' dont l'implémentation en Java est une ArrayList.

Pour la gestion des fichiers de mapping et la génération automatique des objets du domaines et DAO, se reporter au chapitre epcorearchitecture

Utilisation de la propriété lazy

Les liens entre les objets de la base sont nombreux ce qui fait que lorsque l’on accède à un objet, comme un Program ou un Projet, on finit par rechercher et récupérer dans la base tous les échantillons rattachés à ce programme ou projet ainsi que les préparations et séparations subis par les échantillons etc. etc.…

Afin d’optimiser ces accès aux données on utilise le paramètre lazy de hibernate qui permet pour un attribut donné de ne récupérer les valeurs que ci celles-ci sont explicitement demandées. Par exemple, dans la définition d’une étude on a bien la collection des échantillons associés, mais la collection n’est renseignée que si l’on accède à celle-ci, en demandant la liste des échantillons ou en recherchant un échantillon particulier.

Mapping Hibernate :

   <hibernate-mapping>
     <class
            name="cea.edyp.epims.domain.Study"
            table="study"
     >
      <bag
            cascade="delete"
            inverse="true"
            name="samples"              
            lazy="true"
      >
            <key column="study" />
            <one-to-many class="cea.edyp.epims.domain.Sample" />
      </bag>
    </class>

Note De plus, on peut imaginer ajouter dans les services des méthodes « light » permettant de récupérer, par exemple, la liste des noms des échantillons sans pour autant tout récupérer, en utilisant par exemple un accès directe via JDBC.

Problème :

Cette solution semble parfaite mais le problème réside dans son utilisation. En effet, si l’on tente d’accéder à la propriété dite lazy une fois la session hibernate fermée, une exception est générée. Pour éviter toute exception, il ne faut donc pas utiliser directement les méthodes définies dans les objets du domaine.

   public class StudyBean{
      private  Study study_ ;public List getSamples(){
       if(study_ == null)
         return new ArrayList();
       return study_.getSamples();
     }

Une des solutions que l’on retrouve dans les différents forum ou docs, est de récupérer les données lors de la lecture de l’entité si l’on sait que l’on en aura besoin. Cette solution n’est pas convaincante lorsque l’on souhaite séparer complètement la vue des données. En effet, lors du chargement d’une entités au niveau des DAO ou même des Services, on ne connaît pas l’utilisation qui en sera faite.

Solution :

Il est donc nécessaire de définir une méthode qui ouvre la session si nécessaire afin de charger les données lazy sur demande. Une première méthode est définie au niveau des DAO. On retrouve dans IStudyDAO la déclaration de la méthode public void refreshLazy(Study study). Au niveau de l’implémentation, dans EPCoreStudyDAO, lors d’une même session on actualise l’état de l’entité et on accède aux propriétés lazy afin que celles-ci soient chargées.

On ajoute une méthode au niveau des services (interface et implémentation) pour permettre l’accès aux données :

   public List getStudySamples (Study study) {     
     studyDao_.refreshLazy(study);
     return new ArrayList(study.getSamples());
   }

L'utilisateur d'eP-Core verra deux méthodes pour accéder aux données d’une entité : Study.getSample() et IStudyService.getStudySample(Study study). L’utilisation de l’une ou l’autre de ces méthodes entraîne un comportement différent, voire la génération d’une exception dans le premier cas. Un commentaire devra expliquer le comportement de ces méthodes.





(Continuez vers la suite de la documentation ⇒ epcorearchivage)

wiki/epims4_1/developer/epcorehibernate.txt · Last modified: 2008/10/02 10:21 (external edit)