Bonjour,
Aujourd'hui je bosse sur un scénario simple :
J'ai à ma disposition Hibernate et Struts.
Via PL/SQL Developper je vais faire un kill session et je tue la session Oracle.
Comment gérer ça dans monb appli ?
Bonjour,
Aujourd'hui je bosse sur un scénario simple :
J'ai à ma disposition Hibernate et Struts.
Via PL/SQL Developper je vais faire un kill session et je tue la session Oracle.
Comment gérer ça dans monb appli ?
Bon j'ai mis de coté le kill pour simplement faire le test de l'arrachage du cable réseau entre le serveur d'applis et le serveur de BDD.
J'arrive pas à réactiver la connexion...
Je récupère le fait de perdre la connexion puis je lance un reload tel que :
Je merde quelque part car j'ai toujours la même erreur une fois rebranché :
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 public static Session getSession() throws HibernateException { Session s = (Session) session.get(); // Open a new Session, if this Thread has none yet if (s == null||!s.isOpen()) { s = sessionFactory.openSession(); session.set(s); } if(!s.isConnected()){ closeSession(); s = sessionFactory.openSession(); session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); session.set(null); if (s != null) { s.close(); } } public static void reload() throws HibernateException { closeSession(); getSession(); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 17/02/2009 15:05:03 [ERROR] - "Servlet.service()" pour la servlet jsp a lancé une exception java.sql.SQLException: Connexion interrompue
faudrait pas un genre de threading pour qu'il essaye jusqu'à obtenir la dite connection?
opensession va reprendre un connection jdbc dans le pool de connection. T'as vérifié que le pool de connection a bien droppé les connections non valides? Le plus simple est de mettre une requete de validation dans le pool, afin que le pool de connection teste celles-ci avant de les transmettre à Hibernate.
Exemple avec un connection pool oracle configuré dans tomcat:
<Resource name="jdbc/EmployeeDB" auth="Container"
type="javax.sql.DataSource" username="dbusername" password="dbpassword" ..... validationQuery="select 1 from dual"/>
L'openSession est effectivement la meilleure solution. Ce n'etait pas le cas de l'appli que je reprend
Il y avait une gestion de connexion assez merdique. J'ai donc réécris l'Hibernate Util en utilisant celui du site officiel :
Sans oublier cette ligne dans la config d'Hibernate :
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 public class HibernateUtil { private static SessionFactory sessionFactory; private static Configuration configuration; static { // Create the initial SessionFactory from the default configuration // files try { // Read hibernate.properties, if present configuration = new Configuration(); // Use annotations: configuration = new AnnotationConfiguration(); // Read hibernate.cfg.xml (has to be present) configuration.configure(); // Build and store (either in JNDI or static variable) rebuildSessionFactory(configuration); } catch (Throwable ex) { // We have to catch Throwable, otherwise we will miss // NoClassDefFoundError and other subclasses of Error throw new ExceptionInInitializerError(ex); } } /** * Returns the Hibernate configuration that was used to build the * SessionFactory. * * @return Configuration */ public static Configuration getConfiguration() { return configuration; } public static Session getSession() { return HibernateUtil.getSessionFactory().getCurrentSession(); } /** * Returns the global SessionFactory either from a static variable or a JNDI * lookup. * * @return SessionFactory */ private static SessionFactory getSessionFactory() { String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME); if (sfName != null) { try { return (SessionFactory) new InitialContext().lookup(sfName); } catch (NamingException ex) { throw new RuntimeException(ex); } } else if (sessionFactory == null) { rebuildSessionFactory(); } return sessionFactory; } /** * Closes the current SessionFactory and releases all resources. * <p> * The only other method that can be called on HibernateUtil after this one * is rebuildSessionFactory(Configuration). */ public static void shutdown() { // Close caches and connection pools getSessionFactory().close(); // Clear static variables sessionFactory = null; } /** * Rebuild the SessionFactory with the static Configuration. * <p> * Note that this method should only be used with static SessionFactory * management, not with JNDI or any other external registry. This method * also closes the old static variable SessionFactory before, if it is still * open. */ public static void rebuildSessionFactory() { rebuildSessionFactory(configuration); } /** * Rebuild the SessionFactory with the given Hibernate Configuration. * <p> * HibernateUtil does not configure() the given Configuration object, it * directly calls buildSessionFactory(). This method also closes the old * static variable SessionFactory before, if it is still open. * * @param cfg */ public static void rebuildSessionFactory(Configuration cfg) { if (sessionFactory != null && !sessionFactory.isClosed()) sessionFactory.close(); if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null) { cfg.buildSessionFactory(); } else { sessionFactory = cfg.buildSessionFactory(); } configuration = cfg; } }
Utilisation dans un DAO :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 <hibernate-configuration> <session-factory> <!-- Enable Hibernate s automatic session context management --> <property name="current_session_context_class">thread</property> [...] <mapping resource="**/****/metier/beans/TypeMessage.hbm.xml" /> [...] </session-factory> </hibernate-configuration>
Et je catch les exception de type Hibernate et SQL via Struts pour les renvoyer vers une action de type HibernateFailed qui s'occupe de recharger l'ensemble à l'aide du rebuildSessionFactory() de l'HibernateUtil.
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 public Collection getFullGroupe(){ // Récupération de la sassion Session session = HibernateUtil.getSession(); // Déclaratif Collection result = null; try { // Nouvelle transaction session.beginTransaction(); result = session.createQuery("from Groupe order by idGroupe").list(); logger.debug("Requête DAO flux pour retourner la liste des groupe"); // Commit de la session session.getTransaction().commit(); } catch (HibernateException e) { session.getTransaction().rollback(); logger.error("Requête DAO getFullGroupe() exception : " + e); throw e; } return result; }
Après une série de kill en tout genre, cela semble stable.
Merci de votre aide dans tous les cas.
Partager