Pour utiliser ma persistance Hibernate, j'utilise une classe Singleton implementant les différentes methodes d'action sur les objets Hibernate :
Lors de l'utilisation de celle-ci, je procède de la manière suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 public class HibernateManager implements DBAccessManager { private static HibernateManager hibernateManager; private Session session ; private HibernateManager() {} public static synchronized HibernateManager getInstance(){ if (hibernateManager == null) hibernateManager = new HibernateManager(); return hibernateManager ; } public void startSession() { session = HibernateUtil.currentSession(); } public void startTransaction() { try { session.beginTransaction(); } catch (HibernateException he){ he.printStackTrace(); } } public void commit() { session.getTransaction().commit(); } public void rollback() { session.getTransaction().rollback(); } public void save(Object o) { try { session.saveOrUpdate(o); } catch (HibernateException he) { he.printStackTrace(); } } public void closeSession() { HibernateUtil.closeSession(); session=null; } public void updateSession() { try { session.flush(); } catch (HibernateException he) { he.printStackTrace(); } } public void delete(Object o) { try { session.delete(o); } catch (HibernateException he) { he.printStackTrace(); } } public void deleteCollection(Collection collection) { for(Iterator it=collection.iterator();it.hasNext();){ try { session.delete((Object)it.next()); } catch (HibernateException he) { he.printStackTrace(); } } } public void saveCollection(Collection collection) { for(Iterator it=collection.iterator();it.hasNext();){ try { session.saveOrUpdate((Object)it.next()); } catch (HibernateException he) { he.printStackTrace(); } } } public void attach(Object o) { try { session.refresh(o,LockMode.UPGRADE); } catch (HibernateException he) { he.printStackTrace(); } } public void detach(Object o) { try { session.evict(o); } catch (HibernateException he) { he.printStackTrace(); } } public User recupererUser(int id){ Session s = HibernateUtil.currentSession(); Transaction tx = s.beginTransaction(); User us = (User) s.get(User.class,id); tx.commit(); HibernateUtil.closeSession(); return us; } public Fichier recupererFichier(int idFic){ Session s = HibernateUtil.currentSession(); Transaction tx = s.beginTransaction(); Fichier fic = (Fichier) s.get(Fichier.class,idFic); tx.commit(); HibernateUtil.closeSession(); return fic; } @SuppressWarnings("unchecked") public List getUserList() { Criteria criteria = null; List results = null; try { criteria = session.createCriteria(User.class); results = (java.util.List<User>) criteria.list(); } catch (HibernateException he) { he.printStackTrace(); } return results; } }
Or, cette portion de code se retrouve dans plusieurs methode de plusieurs objet differents avec des actions différentes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 manager.startSession(); manager.startTransaction(); manager.attach(Objet); //action sur objet manager.commit(); manager.closeSession();
Travaillant avec Tomcat et des Servlets, ces methodes peuvent être éxécutées simultanéments. Or dans cas, se pose le problème de mon attribut session de mon manager, en effet celui-ci va se retrouvé partagé et si d'un coté une methode appelle le closeSession() et que de l'autre une autre methode est en plein traitement alors elle ne pourra plus travaillé et génèrera une exception.
Même l'utilisation de bloc synchronize(this), ne résoud pas le problème car il empèchera l'execution concurrente au sein de la même méthode pas pour l'ensemble.
Voyez vous un moyen de protéger efficacement ce code car moi je sèche ...
Edit : Voici un morceau de discution privee avec BizuR
Je vois ce que tu veux dire ... mais il me semble que si le prog est executé plusieurs fois (par différents user), la session Factory est propre à un lancement et non à plusieurs ...
Par contre, si tu es en Web (donc un seul lancement), à toi de rendre serializable la session (une par user) ou bien carrément la sessionFactory histoire qu'il se demmerde avec après coup et qu'il fasse comme il l'entend.
Perso, je vois que tu es en sessions courtes... en mode Web, ne serait il pas plus intéressant de caler les session d'Hibernate avec la session Web ?!? Comme ca, a tout nouveau user, tu crées une nouvelle session, et il la garde jusqu'a sa déconnexion ... ca t'évitera, entre autre de couper ta session à chaque opération ... mais bon, après c'est toi qui voit.
Donc en gros, chaque user possède un attribut transcient de session, qui lui est attribué à la connexion par exemple et chaque operation de chaque user est réalisé à partir de sa session. Donc mes methodes de classe restent les même à l'exception qu'elle prennent en attribut la session de l'utilisateur. J'ai bon ?
Partager