001 /*****************************************************************************
002 * Copyright (c) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the license.html file. *
007 * *
008 * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant *
009 *****************************************************************************/
010 package org.nanocontainer.persistence.hibernate;
011
012 import java.io.Serializable;
013 import java.sql.Connection;
014
015 import org.hibernate.CacheMode;
016 import org.hibernate.Criteria;
017 import org.hibernate.EntityMode;
018 import org.hibernate.Filter;
019 import org.hibernate.FlushMode;
020 import org.hibernate.HibernateException;
021 import org.hibernate.Interceptor;
022 import org.hibernate.LockMode;
023 import org.hibernate.Query;
024 import org.hibernate.ReplicationMode;
025 import org.hibernate.SQLQuery;
026 import org.hibernate.Session;
027 import org.hibernate.SessionFactory;
028 import org.hibernate.Transaction;
029 import org.hibernate.stat.SessionStatistics;
030 import org.nanocontainer.persistence.ExceptionHandler;
031 import org.picocontainer.Startable;
032
033 /**
034 * Session component with failover behaviour in case of hibernate exception. Old session is disposed
035 * and new one is obtained transparently. Session creation is done lazily.
036 *
037 * @author Jose Peleteiro <juzepeleteiro@intelli.biz>
038 * @version $Id: SessionComponent.java 2510 2005-09-22 10:11:19Z mauro $
039 */
040 public class SessionComponent implements Session, Startable {
041
042 private Session session = null;
043
044 private SessionFactory sessionFactory;
045 private Interceptor interceptor;
046 protected ExceptionHandler hibernateExceptionHandler;
047
048 public SessionComponent(final SessionFactory sessionFactory) {
049 this.sessionFactory = sessionFactory;
050 hibernateExceptionHandler = new PingPongExceptionHandler();
051 interceptor = null;
052 }
053
054 public SessionComponent(final SessionFactory sessionFactory, final ExceptionHandler hibernateExceptionHandler) {
055 this.sessionFactory = sessionFactory;
056 this.hibernateExceptionHandler = hibernateExceptionHandler;
057 interceptor = null;
058 }
059
060 public SessionComponent(final SessionFactory sessionFactory, final Interceptor interceptor) {
061 this.sessionFactory = sessionFactory;
062 hibernateExceptionHandler = new PingPongExceptionHandler();
063 this.interceptor = interceptor;
064 }
065
066 public SessionComponent(final SessionFactory sessionFactory, final ExceptionHandler hibernateExceptionHandler, final Interceptor interceptor) {
067 this.sessionFactory = sessionFactory;
068 this.hibernateExceptionHandler = hibernateExceptionHandler;
069 this.interceptor = interceptor;
070 }
071
072 /**
073 * Obtain hibernate session.
074 */
075 protected final Session getDelegatedSession(boolean create) {
076 if (create && (session == null)) {
077 try {
078 session = interceptor == null ? sessionFactory.openSession() : sessionFactory.openSession(interceptor);
079 } catch (RuntimeException ex) {
080 throw handleException(ex);
081 }
082 }
083
084 return session;
085 }
086
087 /**
088 * Calls getDelegatedSession(true)
089 */
090 protected final Session getDelegatedSession() {
091 return getDelegatedSession(true);
092 }
093
094 /**
095 * Perform actions to dispose "burned" session properly.
096 */
097 protected void invalidateDelegatedSession() throws HibernateException {
098 if (session != null) {
099 try {
100 session.clear();
101 session.close();
102 } catch (HibernateException ex) {
103 throw handleException(ex);
104 } finally {
105 session = null;
106 }
107 }
108 }
109
110 /**
111 * Invalidates the session calling {@link #invalidateDelegatedSession()} and convert the <code>cause</code> using
112 * a {@link ExceptionHandler} if it's available otherwise just return the <code>cause</code> back.
113 */
114 protected RuntimeException handleException(RuntimeException cause) throws HibernateException {
115 try {
116 invalidateDelegatedSession();
117 } catch (RuntimeException e) {
118 // Do nothing, only the original exception should be reported.
119 }
120
121 return hibernateExceptionHandler.handle(cause);
122 }
123
124 /**
125 * org.picocontainer.Startable.start()
126 */
127 public void start() {
128 // do nothing
129 }
130
131 /**
132 * org.picocontainer.Startable.stop()
133 */
134 public void stop() {
135 close();
136 }
137
138 public Transaction beginTransaction() throws HibernateException {
139 try {
140 return getDelegatedSession().beginTransaction();
141 } catch (RuntimeException ex) {
142 throw handleException(ex);
143 }
144 }
145
146 public void cancelQuery() throws HibernateException {
147 try {
148 getDelegatedSession().cancelQuery();
149 } catch (RuntimeException ex) {
150 throw handleException(ex);
151 }
152 }
153
154 public void clear() {
155 try {
156 if (session == null) {
157 return;
158 }
159
160 session.clear();
161 } catch (RuntimeException ex) {
162 throw handleException(ex);
163 }
164 }
165
166 public Connection close() throws HibernateException {
167 try {
168 if (session == null) {
169 // See Hibernate's javadoc. Returns Connection only when it only was gave by application.
170 return null;
171 }
172
173 return session.close();
174 } catch (RuntimeException ex) {
175 throw handleException(ex);
176 }
177 }
178
179 public Connection connection() throws HibernateException {
180 try {
181 return getDelegatedSession().connection();
182 } catch (RuntimeException ex) {
183 throw handleException(ex);
184 }
185 }
186
187 public boolean contains(Object object) {
188 try {
189 return getDelegatedSession().contains(object);
190 } catch (RuntimeException ex) {
191 throw handleException(ex);
192 }
193 }
194
195 public Criteria createCriteria(Class persistentClass) {
196 try {
197 return getDelegatedSession().createCriteria(persistentClass);
198 } catch (RuntimeException ex) {
199 throw handleException(ex);
200 }
201 }
202
203 public Criteria createCriteria(Class persistentClass, String alias) {
204 try {
205 return getDelegatedSession().createCriteria(persistentClass, alias);
206 } catch (RuntimeException ex) {
207 throw handleException(ex);
208 }
209 }
210
211 public Criteria createCriteria(String entityName) {
212 try {
213 return getDelegatedSession().createCriteria(entityName);
214 } catch (RuntimeException ex) {
215 throw handleException(ex);
216 }
217 }
218
219 public Criteria createCriteria(String entityName, String alias) {
220 try {
221 return getDelegatedSession().createCriteria(entityName, alias);
222 } catch (RuntimeException ex) {
223 throw handleException(ex);
224 }
225 }
226
227 public Query createFilter(Object collection, String queryString) throws HibernateException {
228 try {
229 return getDelegatedSession().createFilter(collection, queryString);
230 } catch (RuntimeException ex) {
231 throw handleException(ex);
232 }
233 }
234
235 public Query createQuery(String queryString) throws HibernateException {
236 try {
237 return getDelegatedSession().createQuery(queryString);
238 } catch (RuntimeException ex) {
239 throw handleException(ex);
240 }
241 }
242
243 public SQLQuery createSQLQuery(String queryString) throws HibernateException {
244 try {
245 return getDelegatedSession().createSQLQuery(queryString);
246 } catch (RuntimeException ex) {
247 throw handleException(ex);
248 }
249 }
250
251 public void delete(Object object) throws HibernateException {
252 try {
253 getDelegatedSession().delete(object);
254 } catch (RuntimeException ex) {
255 throw handleException(ex);
256 }
257 }
258
259 public void disableFilter(String filterName) {
260 try {
261 getDelegatedSession().disableFilter(filterName);
262 } catch (RuntimeException ex) {
263 throw handleException(ex);
264 }
265 }
266
267 public Connection disconnect() throws HibernateException {
268 try {
269 return getDelegatedSession().disconnect();
270 } catch (RuntimeException ex) {
271 throw handleException(ex);
272 }
273 }
274
275 public Filter enableFilter(String filterName) {
276 try {
277 return getDelegatedSession().enableFilter(filterName);
278 } catch (RuntimeException ex) {
279 throw handleException(ex);
280 }
281 }
282
283 public void evict(Object object) throws HibernateException {
284 try {
285 getDelegatedSession().evict(object);
286 } catch (RuntimeException ex) {
287 throw handleException(ex);
288 }
289 }
290
291 public void flush() throws HibernateException {
292 try {
293 if (session == null) {
294 return;
295 }
296
297 session.flush();
298 } catch (RuntimeException ex) {
299 throw handleException(ex);
300 }
301 }
302
303 public Object get(Class clazz, Serializable id) throws HibernateException {
304 try {
305 return getDelegatedSession().get(clazz, id);
306 } catch (RuntimeException ex) {
307 throw handleException(ex);
308 }
309 }
310
311 public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException {
312 try {
313 return getDelegatedSession().get(clazz, id, lockMode);
314 } catch (RuntimeException ex) {
315 throw handleException(ex);
316 }
317 }
318
319 public Object get(String entityName, Serializable id) throws HibernateException {
320 try {
321 return getDelegatedSession().get(entityName, id);
322 } catch (RuntimeException ex) {
323 throw handleException(ex);
324 }
325 }
326
327 public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
328 try {
329 return getDelegatedSession().get(entityName, id, lockMode);
330 } catch (RuntimeException ex) {
331 throw handleException(ex);
332 }
333 }
334
335 public CacheMode getCacheMode() {
336 try {
337 return getDelegatedSession().getCacheMode();
338 } catch (RuntimeException ex) {
339 throw handleException(ex);
340 }
341 }
342
343 public LockMode getCurrentLockMode(Object object) throws HibernateException {
344 try {
345 return getDelegatedSession().getCurrentLockMode(object);
346 } catch (RuntimeException ex) {
347 throw handleException(ex);
348 }
349 }
350
351 public Filter getEnabledFilter(String filterName) {
352 try {
353 return getDelegatedSession().getEnabledFilter(filterName);
354 } catch (RuntimeException ex) {
355 throw handleException(ex);
356 }
357 }
358
359 public EntityMode getEntityMode() {
360 try {
361 return getDelegatedSession().getEntityMode();
362 } catch (RuntimeException ex) {
363 throw handleException(ex);
364 }
365 }
366
367 public String getEntityName(Object object) throws HibernateException {
368 try {
369 return getDelegatedSession().getEntityName(object);
370 } catch (RuntimeException ex) {
371 throw handleException(ex);
372 }
373 }
374
375 public FlushMode getFlushMode() {
376 try {
377 return getDelegatedSession().getFlushMode();
378 } catch (RuntimeException ex) {
379 throw handleException(ex);
380 }
381 }
382
383 public Serializable getIdentifier(Object object) throws HibernateException {
384 try {
385 return getDelegatedSession().getIdentifier(object);
386 } catch (RuntimeException ex) {
387 throw handleException(ex);
388 }
389 }
390
391 public Query getNamedQuery(String queryName) throws HibernateException {
392 try {
393 return getDelegatedSession().getNamedQuery(queryName);
394 } catch (RuntimeException ex) {
395 throw handleException(ex);
396 }
397 }
398
399 public Session getSession(EntityMode entityMode) {
400 try {
401 return getDelegatedSession().getSession(entityMode);
402 } catch (RuntimeException ex) {
403 throw handleException(ex);
404 }
405 }
406
407 public SessionFactory getSessionFactory() {
408 try {
409 return getDelegatedSession().getSessionFactory();
410 } catch (RuntimeException ex) {
411 throw handleException(ex);
412 }
413 }
414
415 public SessionStatistics getStatistics() {
416 try {
417 return getDelegatedSession().getStatistics();
418 } catch (RuntimeException ex) {
419 throw handleException(ex);
420 }
421 }
422
423 public boolean isConnected() {
424 try {
425 return getDelegatedSession().isConnected();
426 } catch (RuntimeException ex) {
427 throw handleException(ex);
428 }
429 }
430
431 public boolean isDirty() throws HibernateException {
432 try {
433 return getDelegatedSession().isDirty();
434 } catch (RuntimeException ex) {
435 throw handleException(ex);
436 }
437 }
438
439 public boolean isOpen() {
440 try {
441 return getDelegatedSession().isOpen();
442 } catch (RuntimeException ex) {
443 throw handleException(ex);
444 }
445 }
446
447 public Object load(Class theClass, Serializable id) throws HibernateException {
448 try {
449 return getDelegatedSession().load(theClass, id);
450 } catch (RuntimeException ex) {
451 throw handleException(ex);
452 }
453 }
454
455 public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException {
456 try {
457 return getDelegatedSession().load(theClass, id, lockMode);
458 } catch (RuntimeException ex) {
459 throw handleException(ex);
460 }
461 }
462
463 public void load(Object object, Serializable id) throws HibernateException {
464 try {
465 getDelegatedSession().load(object, id);
466 } catch (RuntimeException ex) {
467 throw handleException(ex);
468 }
469 }
470
471 public Object load(String entityName, Serializable id) throws HibernateException {
472 try {
473 return getDelegatedSession().load(entityName, id);
474 } catch (RuntimeException ex) {
475 throw handleException(ex);
476 }
477 }
478
479 public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
480 try {
481 return getDelegatedSession().load(entityName, id, lockMode);
482 } catch (RuntimeException ex) {
483 throw handleException(ex);
484 }
485 }
486
487 public void lock(Object object, LockMode lockMode) throws HibernateException {
488 try {
489 getDelegatedSession().lock(object, lockMode);
490 } catch (RuntimeException ex) {
491 throw handleException(ex);
492 }
493 }
494
495 public void lock(String entityEntity, Object object, LockMode lockMode) throws HibernateException {
496 try {
497 getDelegatedSession().lock(entityEntity, object, lockMode);
498 } catch (RuntimeException ex) {
499 throw handleException(ex);
500 }
501 }
502
503 public Object merge(Object object) throws HibernateException {
504 try {
505 return getDelegatedSession().merge(object);
506 } catch (RuntimeException ex) {
507 throw handleException(ex);
508 }
509 }
510
511 public Object merge(String entityName, Object object) throws HibernateException {
512 try {
513 return getDelegatedSession().merge(entityName, object);
514 } catch (RuntimeException ex) {
515 throw handleException(ex);
516 }
517 }
518
519 public void persist(Object object) throws HibernateException {
520 try {
521 getDelegatedSession().persist(object);
522 } catch (RuntimeException ex) {
523 throw handleException(ex);
524 }
525 }
526
527 public void persist(String entityName, Object object) throws HibernateException {
528 try {
529 getDelegatedSession().persist(entityName, object);
530 } catch (RuntimeException ex) {
531 throw handleException(ex);
532 }
533 }
534
535 public void reconnect() throws HibernateException {
536 try {
537 getDelegatedSession().reconnect();
538 } catch (RuntimeException ex) {
539 throw handleException(ex);
540 }
541 }
542
543 public void reconnect(Connection conn) throws HibernateException {
544 try {
545 getDelegatedSession().reconnect(conn);
546 } catch (RuntimeException ex) {
547 throw handleException(ex);
548 }
549 }
550
551 public void refresh(Object object) throws HibernateException {
552 try {
553 getDelegatedSession().refresh(object);
554 } catch (RuntimeException ex) {
555 throw handleException(ex);
556 }
557 }
558
559 public void refresh(Object object, LockMode lockMode) throws HibernateException {
560 try {
561 getDelegatedSession().refresh(object, lockMode);
562 } catch (RuntimeException ex) {
563 throw handleException(ex);
564 }
565 }
566
567 public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException {
568 try {
569 getDelegatedSession().replicate(object, replicationMode);
570 } catch (RuntimeException ex) {
571 throw handleException(ex);
572 }
573 }
574
575 public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException {
576 try {
577 getDelegatedSession().replicate(entityName, object, replicationMode);
578 } catch (RuntimeException ex) {
579 throw handleException(ex);
580 }
581 }
582
583 public Serializable save(Object object) throws HibernateException {
584 try {
585 return getDelegatedSession().save(object);
586 } catch (RuntimeException ex) {
587 throw handleException(ex);
588 }
589 }
590
591 public void save(Object object, Serializable id) throws HibernateException {
592 try {
593 getDelegatedSession().save(object, id);
594 } catch (RuntimeException ex) {
595 throw handleException(ex);
596 }
597 }
598
599 public Serializable save(String entityName, Object object) throws HibernateException {
600 try {
601 return getDelegatedSession().save(entityName, object);
602 } catch (RuntimeException ex) {
603 throw handleException(ex);
604 }
605 }
606
607 public void save(String entityName, Object object, Serializable id) throws HibernateException {
608 try {
609 getDelegatedSession().save(entityName, object, id);
610 } catch (RuntimeException ex) {
611 throw handleException(ex);
612 }
613 }
614
615 public void saveOrUpdate(Object object) throws HibernateException {
616 try {
617 getDelegatedSession().saveOrUpdate(object);
618 } catch (RuntimeException ex) {
619 throw handleException(ex);
620 }
621 }
622
623 public void saveOrUpdate(String entityName, Object object) throws HibernateException {
624 try {
625 getDelegatedSession().saveOrUpdate(entityName, object);
626 } catch (RuntimeException ex) {
627 throw handleException(ex);
628 }
629 }
630
631 public void setCacheMode(CacheMode cacheMode) {
632 try {
633 getDelegatedSession().setCacheMode(cacheMode);
634 } catch (RuntimeException ex) {
635 throw handleException(ex);
636 }
637 }
638
639 public void setFlushMode(FlushMode value) {
640 try {
641 getDelegatedSession().setFlushMode(value);
642 } catch (RuntimeException ex) {
643 throw handleException(ex);
644 }
645 }
646
647 public void update(Object object) throws HibernateException {
648 try {
649 getDelegatedSession().update(object);
650 } catch (RuntimeException ex) {
651 throw handleException(ex);
652 }
653 }
654
655 public void update(Object object, Serializable id) throws HibernateException {
656 try {
657 getDelegatedSession().update(object, id);
658 } catch (RuntimeException ex) {
659 throw handleException(ex);
660 }
661 }
662
663 public void update(String entityName, Object object) throws HibernateException {
664 try {
665 getDelegatedSession().update(entityName, object);
666 } catch (RuntimeException ex) {
667 throw handleException(ex);
668 }
669 }
670
671 public void update(String entityName, Object object, Serializable id) throws HibernateException {
672 try {
673 getDelegatedSession().update(entityName, object, id);
674 } catch (RuntimeException ex) {
675 throw handleException(ex);
676 }
677 }
678
679 /**
680 * A not to do "if (handler == null)" ping-pong ExceptionHandler version.
681 */
682 private class PingPongExceptionHandler implements ExceptionHandler {
683
684 public RuntimeException handle(Throwable ex) {
685 return (RuntimeException) ex;
686 }
687
688 }
689
690 }