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
011 package org.nanocontainer.persistence.hibernate;
012
013 import java.sql.Connection;
014
015 import org.hibernate.HibernateException;
016 import org.hibernate.Interceptor;
017 import org.hibernate.Session;
018 import org.hibernate.SessionFactory;
019 import org.nanocontainer.persistence.ExceptionHandler;
020
021 /**
022 * Session delegator with failover behaviour in case of hibernate exception. Old session is disposed
023 * and new one is obtained transparently. Session creation is done lazily.
024 *
025 * @author Jose Peleteiro <juzepeleteiro@intelli.biz>
026 * @version $Revision: 2043 $
027 */
028 public class FailoverSessionDelegator extends SessionDelegator {
029
030 private SessionFactory sessionFactory;
031 private Session session = null;
032 private Interceptor interceptor = null;
033
034 /**
035 * @param sessionFactory session factory to obtain session from
036 */
037 public FailoverSessionDelegator(SessionFactory sessionFactory) {
038 this.sessionFactory = sessionFactory;
039 }
040
041 /**
042 * @param sessionFactory session factory to obtain session from
043 * @param exceptionHandler Exception handler component to use with created session
044 */
045 public FailoverSessionDelegator(SessionFactory sessionFactory, ExceptionHandler exceptionHandler) {
046 super(exceptionHandler);
047 this.sessionFactory = sessionFactory;
048 }
049
050 /**
051 * @param sessionFactory sessionf actory to obtain session from
052 * @param interceptor interceptor to use with created session
053 */
054 public FailoverSessionDelegator(SessionFactory sessionFactory, Interceptor interceptor) {
055 this(sessionFactory);
056 setInterceptor(interceptor);
057 }
058
059 /**
060 * @param sessionFactory sessionf actory to obtain session from
061 * @param interceptor interceptor to use with created session
062 * @param exceptionHandler Exception handler component to use with created session
063 */
064 public FailoverSessionDelegator(SessionFactory sessionFactory, Interceptor interceptor, ExceptionHandler exceptionHandler) {
065 this(sessionFactory, exceptionHandler);
066 setInterceptor(interceptor);
067 }
068
069 public SessionFactory getSessionFactory() {
070 return sessionFactory;
071 }
072
073 /**
074 * Obtain hibernate session in lazy way.
075 */
076 public Session getDelegatedSession() {
077 if (session == null) {
078 try {
079 session = interceptor == null ? sessionFactory.openSession() : sessionFactory.openSession(interceptor);
080 } catch (RuntimeException ex) {
081 throw handleException(ex);
082 }
083 }
084
085 return session;
086 }
087
088 public Connection close() throws HibernateException {
089 try {
090 return getDelegatedSession().close();
091 } catch (HibernateException ex) {
092 session = null;
093 throw handleException(ex);
094 } finally {
095 session = null;
096 }
097 }
098
099 public void invalidateDelegatedSession() throws HibernateException {
100 if (this.session != null) {
101 try {
102 session.clear();
103 session.close();
104 } catch (HibernateException ex) {
105 session = null;
106 throw handleException(ex);
107 } finally {
108 session = null;
109 }
110 }
111 }
112
113 public Interceptor getInterceptor() {
114 return interceptor;
115 }
116
117 public void setInterceptor(Interceptor interceptor) {
118 this.interceptor = interceptor;
119 }
120
121 }