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