[ALG3-iR Java] Sessions - Bonnes pratiques

Voir le sujet précédent Voir le sujet suivant Aller en bas

[ALG3-iR Java] Sessions - Bonnes pratiques

Message  Wark le Ven 25 Déc 2009, 15:06

Bonjour,

Je suis en plein projet 2 et j'ai quelques soucis concernant la gestion des sessions Hibernate.. Voici mon problème, actuellement, je possède une variable de type Session (statique) par classe de DB. Chaque méthode commence donc par :

Code:

(if session != null && session.isOpen()) session.close();
ClasseUtil.getSessionFactory().openSession();

Ce code fonctionne très bien dans la majorité des cas. Cela étant, il m'arrive d'avoir des soucis de non-rafraichissement des données persistantes (donc, en mémoire) d'Hibernate. Les données sont bien dans la BD (via MySQL Administrator ou même en relançant le programme) mais dans la même exécution, l'état des objets Hibernate n'est pas celui de la base de données.

Une, très mauvaise, solution que j'ai pu trouvée est de fermer carrément le sessionFactory... mais c'est moche et surtout très lourd.

Du coup, je me suis mis en quête de "Good Practice" ou d'une architecture permettant la gestion unique de sessions.. (J'ai suivi les tutoriels Netbeans et Hibernate et je n'ai pas aperçu de réelle solution).

Merci d'avance pour les réponses et Joyeux Noël santa

Wark

Nombre de messages : 682
Age : 29
Prénom : Cédric
Statut : Diplômé 2010
Localisation : Braine l'alleud
Date d'inscription : 04/02/2008

Revenir en haut Aller en bas

Re: [ALG3-iR Java] Sessions - Bonnes pratiques

Message  aro le Dim 27 Déc 2009, 12:14

Wark a écrit:Bonjour,

Je suis en plein projet 2 et j'ai quelques soucis concernant la gestion des sessions Hibernate.. Voici mon problème, actuellement, je possède une variable de type Session (statique) par classe de DB. Chaque méthode commence donc par :
Code:

(if session != null && session.isOpen()) session.close();
ClasseUtil.getSessionFactory().openSession();
Si la session est fermée au début de chaque méthode, pourquoi une variable statique ?
Il n’y a pas forcément de "bonne pratique" qui convienne toujours car cela dépend très fort de l’application, de la db, des besoins (read only,..),…
Il y a cependant un choix à faire : est-ce qu’une session est partagée par plusieurs requêtes (ou plusieurs méthodes) ou non.

Si non, une variable session locale (session ouverte au début de la méthode et fermée à la fin) suffit. Comme le montre l’exemple dans la doc de l’API Session :
Code:
Session session = factory.openSession();
Transaction tx;
try {
      tx = session.beginTransaction();
      //do some work      ...
      tx.commit();
}  catch (Exception e) {
      if (tx!=null) tx.rollback();
      throw e;
}  finally {
      session.close();
}

Si oui, une variable statique dans une classe à part peut effectivement être utilisée pour partager la session entre plusieurs classes db. L’appel d’une méthode de Session sera donc précédé d’un getSession qui retourne la session courante (ou en ouvre une s’il n’y a pas de session courante).

Wark a écrit:Ce code fonctionne très bien dans la majorité des cas. Cela étant, il m'arrive d'avoir des soucis de non-rafraichissement des données persistantes (donc, en mémoire) d'Hibernate. Les données sont bien dans la BD (via MySQL Administrator ou même en relançant le programme) mais dans la même exécution, l'état des objets Hibernate n'est pas celui de la base de données.
Pour réfléchir à une solution, il faudrait isoler un cas reproductible où cela ne fonctionne pas ;-)
Normalement, en utilisant les transactions, les données doivent être synchros => quand est-ce que ce n’est pas le cas ?

Wark a écrit:Du coup, je me suis mis en quête de "Good Practice" ou d'une architecture permettant la gestion unique de sessions.. (J'ai suivi les tutoriels Netbeans et Hibernate et je n'ai pas aperçu de réelle solution).
Tu as été voir là https://www.hibernate.org/42.html et là http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html ?

aro

Nombre de messages : 557
Prénom : Anne
Statut : Prof
Date d'inscription : 06/09/2008

Revenir en haut Aller en bas

Re: [ALG3-iR Java] Sessions - Bonnes pratiques

Message  Wark le Dim 27 Déc 2009, 13:19

Merci de votre réponse, j'ai bien consulté cela.

Le seul cas reproductible, c'est lorsque je delete en cascade dans d'autres tables, en fait, j'ai ajouté la condition "cascade=delete-orphan" dans le fichier xml. Je supprime donc un "Client", ce qui a pour but de supprimer l'ensemble de ses "Compte" associés. La suppression s'effectue correctement pour le client ... mais l'ensemble des comptes est toujours référencé dans la liste des comptes (récupérées via une requête type Criteria). Si je redémarre l'application, mes comptes ont bien disparus (ils n'étaient déjà plus dans la BD mais étaient toujours référencés par Hibernate).

L'utilisation d'une variable statique est effectivement inutile.. par contre, si je ne fais pas cela, lorsqu'avec ma liste de clients, par exemple, je souhaite accéder à un champ de son adresse par :

Code:
client.getAdresse().getRue();

Hibernate me retourne un "Proxy error : Session is closed" alors que :

Code:
client.getNom();

fonctionne très bien..

* Edit *

Cette variable est statique car elle est utilisée dans des fonctions statiques, elle est partagée car les fonctions retournant une liste effectuée avec Criteria ne la ferment pas .. (erreur de codage ? Une simple requête Criteria doit également se trouver dans une transaction ?). Du coup, ce problème engendre des erreurs de type "2 sessions ouvertes sur la même collection".

Wark

Nombre de messages : 682
Age : 29
Prénom : Cédric
Statut : Diplômé 2010
Localisation : Braine l'alleud
Date d'inscription : 04/02/2008

Revenir en haut Aller en bas

Re: [ALG3-iR Java] Sessions - Bonnes pratiques

Message  aro le Dim 27 Déc 2009, 16:02

Wark a écrit:Le seul cas reproductible, c'est lorsque je delete en cascade dans d'autres tables, en fait, j'ai ajouté la condition "cascade=delete-orphan" dans le fichier xml. Je supprime donc un "Client", ce qui a pour but de supprimer l'ensemble de ses "Compte" associés. La suppression s'effectue correctement pour le client ... mais l'ensemble des comptes est toujours référencé dans la liste des comptes (récupérées via une requête type Criteria). Si je redémarre l'application, mes comptes ont bien disparus (ils n'étaient déjà plus dans la BD mais étaient toujours référencés par Hibernate).
Et, avec cascade="all,delete-orphan" à la place ? Ou aller voir du côté des caches ?
Wark a écrit:L'utilisation d'une variable statique est effectivement inutile.. par contre, si je ne fais pas cela, lorsqu'avec ma liste de clients, par exemple, je souhaite accéder à un champ de son adresse par :

Code:
client.getAdresse().getRue();

Hibernate me retourne un "Proxy error : Session is closed" alors que :

Code:
client.getNom();

fonctionne très bien..
Cela, c’est aussi à cause du lazy loading et ce pourrait être une optimisation de le désactiver pour certaines collections ou pour certaines références à d'autres entitiés. Comme cela pourrait être une optimisation de choisir "fetch=join" (ce qui désactive aussi le lazy loading) pour certaines relations. Ou encore utiliser initialize, ou... A nouveau, choisir l’une ou l’autre stratégie dépendra de l’appli, de la db,...
Un peu de lecture : http://www.javadev.org/files/Hibernate%20Performance%20Tuning.pdf

Wark a écrit:* Edit *

Cette variable est statique car elle est utilisée dans des fonctions statiques, elle est partagée car les fonctions retournant une liste effectuée avec Criteria ne la ferment pas .. (erreur de codage ? Une simple requête Criteria doit également se trouver dans une transaction ?). Du coup, ce problème engendre des erreurs de type "2 sessions ouvertes sur la même collection".
Il y a cela aussi : www.devarticles.com/c/a/Java/Managing-Transactions-with-Hibernate/3/

aro

Nombre de messages : 557
Prénom : Anne
Statut : Prof
Date d'inscription : 06/09/2008

Revenir en haut Aller en bas

Re: [ALG3-iR Java] Sessions - Bonnes pratiques

Message  Wark le Dim 27 Déc 2009, 22:14

Merci pour votre lecture, effectivement, j'avais fait précédemment un test en désactivant "lazy", ceci dit, c'est forcément moins performant...

Je vais lire tout cela.

Wark

Nombre de messages : 682
Age : 29
Prénom : Cédric
Statut : Diplômé 2010
Localisation : Braine l'alleud
Date d'inscription : 04/02/2008

Revenir en haut Aller en bas

Re: [ALG3-iR Java] Sessions - Bonnes pratiques

Message  Contenu sponsorisé Aujourd'hui à 12:33


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut


 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum