1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hivetranse.transaction.hibernate3; |
16 | |
17 | import java.util.HashMap; |
18 | import java.util.Iterator; |
19 | import java.util.Map; |
20 | |
21 | import org.apache.commons.logging.Log; |
22 | import org.apache.commons.logging.LogFactory; |
23 | |
24 | import org.hibernate.HibernateException; |
25 | import org.hibernate.SessionFactory; |
26 | import org.hibernate.Transaction; |
27 | import org.hibernate.classic.Session; |
28 | |
29 | /** |
30 | * Actual implementation class for <code>SessionsRepository</code>. |
31 | * Enlisted sessions and transactions are stored in a <code>Map</code>. |
32 | * |
33 | * @author Jean-Francois Poilpret |
34 | */ |
35 | public class SessionsRepositoryImpl implements SessionsRepository |
36 | { |
37 | static final private Log _logger = LogFactory.getLog(SessionsRepositoryImpl.class); |
38 | |
39 | public Session getSession(String id, SessionFactory factory) |
40 | { |
41 | TransactionEntry entry = _sessions.get(id); |
42 | if (entry == null) |
43 | { |
44 | entry = openSession(factory); |
45 | _sessions.put(id, entry); |
46 | } |
47 | return entry.getSession(); |
48 | } |
49 | |
50 | public void endAllSessions(boolean close, boolean commit) |
51 | { |
52 | HibernateException exc = null; |
53 | HibernateException e; |
54 | Iterator<Map.Entry<String, TransactionEntry>> i = _sessions.entrySet().iterator(); |
55 | while (i.hasNext()) |
56 | { |
57 | Map.Entry<String, TransactionEntry> entry = i.next(); |
58 | String id = entry.getKey(); |
59 | TransactionEntry txEntry = entry.getValue(); |
60 | e = terminateTransaction(id, txEntry.getTransaction(), commit); |
61 | if (e != null && exc == null) |
62 | { |
63 | // We keep track only of the first exception occurring |
64 | exc = e; |
65 | } |
66 | if (close) |
67 | { |
68 | // Session will not close; is that a problem? |
69 | e = closeSession(id, txEntry.getSession()); |
70 | if (e != null && exc == null) |
71 | { |
72 | // We keep track only of the first exception occurring |
73 | exc = e; |
74 | } |
75 | i.remove(); |
76 | } |
77 | else |
78 | { |
79 | // We are in "open session in view" case, we must reopen a new |
80 | // transaction and put into TransactionEntry |
81 | e = openTransaction(txEntry); |
82 | if (e != null && exc == null) |
83 | { |
84 | // We keep track only of the first exception occurring |
85 | exc = e; |
86 | } |
87 | } |
88 | } |
89 | if (exc != null) |
90 | { |
91 | throw exc; |
92 | } |
93 | } |
94 | |
95 | protected HibernateException terminateTransaction( String id, |
96 | Transaction tx, |
97 | boolean commit) |
98 | { |
99 | try |
100 | { |
101 | if (commit) |
102 | { |
103 | tx.commit(); |
104 | } |
105 | else |
106 | { |
107 | tx.rollback(); |
108 | } |
109 | return null; |
110 | } |
111 | catch (HibernateException e) |
112 | { |
113 | _logger.warn("terminateTransaction", e); |
114 | return e; |
115 | } |
116 | } |
117 | |
118 | protected HibernateException closeSession(String id, Session session) |
119 | { |
120 | try |
121 | { |
122 | session.close(); |
123 | return null; |
124 | } |
125 | catch (HibernateException e) |
126 | { |
127 | _logger.warn("closeSession", e); |
128 | return e; |
129 | } |
130 | } |
131 | |
132 | protected TransactionEntry openSession(SessionFactory factory) |
133 | { |
134 | try |
135 | { |
136 | Session s = factory.openSession(); |
137 | Transaction tx = s.beginTransaction(); |
138 | return new TransactionEntry(s, tx); |
139 | } |
140 | catch (HibernateException e) |
141 | { |
142 | _logger.warn("openSession", e); |
143 | throw e; |
144 | } |
145 | } |
146 | |
147 | protected HibernateException openTransaction(TransactionEntry entry) |
148 | { |
149 | try |
150 | { |
151 | Session s = entry.getSession(); |
152 | Transaction tx = s.beginTransaction(); |
153 | entry.setTransaction(tx); |
154 | return null; |
155 | } |
156 | catch (HibernateException e) |
157 | { |
158 | _logger.warn("openTransaction", e); |
159 | return e; |
160 | } |
161 | } |
162 | |
163 | static protected class TransactionEntry |
164 | { |
165 | public TransactionEntry(Session session, Transaction tx) |
166 | { |
167 | _session = session; |
168 | _tx = tx; |
169 | } |
170 | |
171 | public Session getSession() |
172 | { |
173 | return _session; |
174 | } |
175 | |
176 | public Transaction getTransaction() |
177 | { |
178 | return _tx; |
179 | } |
180 | |
181 | public void setTransaction(Transaction tx) |
182 | { |
183 | _tx = tx; |
184 | } |
185 | |
186 | private final Session _session; |
187 | private Transaction _tx; |
188 | } |
189 | |
190 | private final Map<String, TransactionEntry> _sessions = |
191 | new HashMap<String, TransactionEntry>(); |
192 | } |