KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > jdbc > JDBCContext


1 // $Id: JDBCContext.java,v 1.15 2005/07/06 22:21:25 epbernard Exp $
2
package org.hibernate.jdbc;
3
4 import java.io.Serializable JavaDoc;
5 import java.sql.Connection JavaDoc;
6 import java.sql.SQLException JavaDoc;
7 import javax.transaction.TransactionManager JavaDoc;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.hibernate.ConnectionReleaseMode;
12 import org.hibernate.HibernateException;
13 import org.hibernate.SessionException;
14 import org.hibernate.Transaction;
15 import org.hibernate.TransactionException;
16 import org.hibernate.engine.SessionFactoryImplementor;
17 import org.hibernate.exception.JDBCExceptionHelper;
18 import org.hibernate.transaction.CacheSynchronization;
19 import org.hibernate.transaction.TransactionFactory;
20 import org.hibernate.util.JTAHelper;
21
22 /**
23  * Acts as the mediary between "entity-mode related" sessions in terms of
24  * their interaction with the JDBC data store.
25  *
26  * @author Steve Ebersole
27  */

28 public class JDBCContext implements Serializable JavaDoc, ConnectionManager.Callback {
29
30     // TODO : make this the factory for "entity mode related" sessions;
31
// also means making this the target of transaction-synch and the
32
// thing that knows how to cascade things between related sessions
33
//
34
// At that point, perhaps this thing is a "SessionContext", and
35
// ConnectionManager is a "JDBCContext"? A "SessionContext" should
36
// live in the impl package...
37

38     private static final Log log = LogFactory.getLog( JDBCContext.class );
39
40     public static interface Context extends TransactionFactory.Context {
41         public void beforeTransactionCompletion(org.hibernate.Transaction tx);
42         public void afterTransactionCompletion(boolean success, org.hibernate.Transaction tx);
43         public ConnectionReleaseMode getConnectionReleaseMode();
44         public boolean isAutoCloseSessionEnabled();
45     }
46
47     private Context owner;
48     private ConnectionManager connectionManager;
49     private boolean isTransactionCallbackRegistered;
50     private boolean isHibernateTransactionActive;
51
52     public JDBCContext(Context owner, Connection JavaDoc connection) {
53         this.owner = owner;
54         this.connectionManager = new ConnectionManager(
55                 owner.getFactory(),
56                 this,
57                 owner.getConnectionReleaseMode(),
58                 connection
59         );
60
61         final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
62                 || owner.isFlushBeforeCompletionEnabled()
63                 || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
64         if ( registerSynchronization ) {
65             registerSynchronizationIfPossible();
66         }
67     }
68
69
70     // ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71

72     public void connectionOpened() {
73         if ( !isTransactionCallbackRegistered ) {
74             // If there is no current transaction callback registered
75
// when we obtain a connection, try to register one now.
76
// Note that this is not going to handle the case of
77
// multiple-transactions-per-connection when the user is
78
// manipulating transactions (need to use Hibernate txn)
79
registerSynchronizationIfPossible();
80         }
81
82         if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
83             owner.getFactory().getStatisticsImplementor().connect();
84         }
85     }
86
87     public void connectionCleanedUp() {
88         if ( !isTransactionCallbackRegistered ) {
89             afterTransactionCompletion( false, null );
90             // Note : success = false, because we don't know the outcome of the transaction
91
}
92     }
93
94     public SessionFactoryImplementor getFactory() {
95         return owner.getFactory();
96     }
97
98     public ConnectionManager getConnectionManager() {
99         return connectionManager;
100     }
101     
102 // private void releaseConnection() {
103
// if ( connection!=null ) {
104
// batcher.closeConnection( connection );
105
// connection = null;
106
// connect = true;
107
// }
108
// }
109

110 // public boolean isConnected() {
111
// return connection != null || connect;
112
// }
113

114 // public boolean isSerializable() {
115
// return connection==null;
116
// }
117

118 // public Connection release() {
119
// if (connection==null) {
120
// connect = false;
121
// return null;
122
// }
123
// else {
124
// return disconnect();
125
// }
126
// }
127

128     public Connection JavaDoc connection() throws HibernateException {
129         if ( !owner.isOpen() ) {
130             throw new SessionException( "Session is closed" );
131         }
132         else if ( !connectionManager.isLogicallyConnected() ) {
133             throw new SessionException( "Session is currently disconnected" );
134         }
135
136         return connectionManager.getConnection();
137     }
138
139 // public Connection connection() throws HibernateException {
140
// if (connection==null) {
141
// if (connect) {
142
// connect();
143
// }
144
// else if ( owner.isOpen() ) {
145
//
146
// }
147
// else {
148
// throw new SessionException("Session is closed");
149
// }
150
// }
151
// return connection;
152
// }
153

154     public boolean registerCallbackIfNecessary() {
155         if ( isTransactionCallbackRegistered ) {
156             return false;
157         }
158         else {
159             isTransactionCallbackRegistered = true;
160             return true;
161         }
162
163     }
164
165     public boolean registerSynchronizationIfPossible() {
166         if ( isTransactionCallbackRegistered ) return true;
167         TransactionManager JavaDoc tm = owner.getFactory().getTransactionManager();
168         if ( tm == null ) {
169             return false;
170         }
171         else {
172             try {
173                 javax.transaction.Transaction JavaDoc tx = tm.getTransaction();
174                 if ( JTAHelper.isTransactionInProgress(tx) ) {
175                     tx.registerSynchronization( new CacheSynchronization(owner, this, tx, null) );
176                     isTransactionCallbackRegistered = true;
177                     log.debug("successfully registered Synchronization");
178                     return true;
179                 }
180                 else {
181                     log.debug("no active transaction, could not register Synchronization");
182                     return false;
183                 }
184             }
185             catch (Exception JavaDoc e) {
186                 throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
187             }
188         }
189     }
190     
191     public boolean isTransactionInProgress() {
192         if ( isHibernateTransactionActive ) {
193             return true;
194         }
195         else {
196             return JTAHelper.isTransactionInProgress( owner.getFactory() );
197         }
198     }
199
200 // private void connect() throws HibernateException {
201
// connection = batcher.openConnection();
202
// connect = false;
203
// if ( !isTransactionCallbackRegistered ) {
204
// //if there is no current transaction callback registered
205
// //when we obtain the connection, try to register one now
206
// //note that this is not going to handle the case of
207
// //multiple-transactions-per-connection when the user is
208
// //manipulating transactions (need to use Hibernate txn)
209
// registerSynchronizationIfPossible();
210
// }
211
//
212
// if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
213
// owner.getFactory().getStatisticsImplementor().connect();
214
// }
215
//
216
// }
217

218 // public Connection disconnect() throws HibernateException {
219
// try {
220
// if (connect) {
221
// connect = false;
222
// return null;
223
// }
224
// else {
225
// if (connection==null) {
226
// throw new HibernateException( "Already disconnected" );
227
// }
228
//
229
// batcher.closeStatements();
230
// Connection c = connection;
231
// connection = null;
232
// if ( autoClose ) {
233
// batcher.closeConnection( c );
234
// return null;
235
// }
236
// else {
237
// return c;
238
// }
239
// }
240
// }
241
// finally {
242
// if ( !isTransactionCallbackRegistered ) {
243
// afterTransactionCompletion( false, null ); //false because we don't know the outcome of the transaction
244
// }
245
// }
246
// }
247

248 // public void reconnect() throws HibernateException {
249
// if ( isConnected() ) throw new HibernateException( "Already connected" );
250
// if ( !owner.isOpen() ) throw new HibernateException( "Session is closed" );
251
//
252
// log.debug( "reconnecting session" );
253
//
254
// connect = true;
255
// //connection = factory.openConnection();
256
// }
257
//
258
// public void reconnect(Connection conn) throws HibernateException {
259
// if ( isConnected() ) throw new HibernateException( "Already connected" );
260
// this.connection = conn;
261
// }
262

263     public Transaction beginTransaction() throws HibernateException {
264         Transaction tx = owner.getFactory().getSettings().getTransactionFactory()
265                 .beginTransaction( this, owner );
266         isHibernateTransactionActive = true;
267         return tx;
268     }
269
270     public void beforeTransactionCompletion(Transaction tx) {
271         log.trace( "before transaction completion" );
272         owner.beforeTransactionCompletion(tx);
273     }
274
275     public void afterTransactionCompletion(boolean success, Transaction tx) {
276         log.trace( "after transaction completion" );
277
278         if ( getFactory().getStatistics().isStatisticsEnabled() ) {
279             getFactory().getStatisticsImplementor().endTransaction(success);
280         }
281
282         connectionManager.afterTransaction();
283 // releaseConnectionAfterTransaction();
284

285         isTransactionCallbackRegistered = false;
286         isHibernateTransactionActive = false;
287         owner.afterTransactionCompletion(success, tx);
288     }
289
290 // /**
291
// * Release the connection if we are in AFTER_STATEMENT
292
// * connection release mode
293
// */
294
// void releaseConnectionAfterStatement() {
295
// if ( owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_STATEMENT ) {
296
// releaseConnection();
297
// }
298
// }
299

300 // /**
301
// * Release the connection if we are in AFTER_TRANSACTION
302
// * connection release mode
303
// */
304
// void releaseConnectionAfterTransaction() {
305
// if ( owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION ) {
306
// releaseConnection();
307
// }
308
// }
309

310     /**
311      * Called after executing a query outside the scope of
312      * a Hibernate or JTA transaction
313      */

314     public void afterNontransactionalQuery(boolean success) {
315         log.trace( "after autocommit" );
316         try {
317             // check to see if the connection is in auto-commit
318
// mode (no connection means aggressive connection
319
// release outside a JTA transaction context, so MUST
320
// be autocommit mode)
321
boolean isAutocommit = connectionManager.isAutoCommit();
322
323             connectionManager.afterTransaction();
324             
325             if ( isAutocommit ) {
326                 owner.afterTransactionCompletion(success, null);
327             }
328         }
329         catch (SQLException JavaDoc sqle) {
330             success = false;
331             throw JDBCExceptionHelper.convert(
332                     owner.getFactory().getSQLExceptionConverter(),
333                     sqle,
334                     "could not inspect JDBC autocommit mode"
335                 );
336         }
337     }
338 }
339
Popular Tags