1 16 17 package org.springframework.orm.hibernate3; 18 19 import java.lang.reflect.InvocationHandler ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Proxy ; 23 24 import org.apache.commons.logging.Log; 25 import org.apache.commons.logging.LogFactory; 26 import org.hibernate.HibernateException; 27 import org.hibernate.JDBCException; 28 import org.hibernate.SessionFactory; 29 import org.hibernate.engine.SessionFactoryImplementor; 30 31 import org.springframework.beans.factory.DisposableBean; 32 import org.springframework.beans.factory.FactoryBean; 33 import org.springframework.beans.factory.InitializingBean; 34 import org.springframework.dao.DataAccessException; 35 import org.springframework.dao.support.PersistenceExceptionTranslator; 36 import org.springframework.jdbc.support.SQLExceptionTranslator; 37 38 61 public abstract class AbstractSessionFactoryBean 62 implements FactoryBean, InitializingBean, DisposableBean, PersistenceExceptionTranslator { 63 64 65 protected final Log logger = LogFactory.getLog(getClass()); 66 67 private boolean exposeTransactionAwareSessionFactory = true; 68 69 private SQLExceptionTranslator jdbcExceptionTranslator; 70 71 private SessionFactory sessionFactory; 72 73 74 99 public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) { 100 this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory; 101 } 102 103 106 protected boolean isExposeTransactionAwareSessionFactory() { 107 return exposeTransactionAwareSessionFactory; 108 } 109 110 123 public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) { 124 this.jdbcExceptionTranslator = jdbcExceptionTranslator; 125 } 126 127 128 133 public void afterPropertiesSet() throws Exception { 134 SessionFactory rawSf = buildSessionFactory(); 135 this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf); 136 afterSessionFactoryCreation(); 137 } 138 139 146 protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) { 147 if (isExposeTransactionAwareSessionFactory()) { 148 return getTransactionAwareSessionFactoryProxy(rawSf); 149 } 150 else { 151 return rawSf; 152 } 153 } 154 155 164 protected SessionFactory getTransactionAwareSessionFactoryProxy(SessionFactory target) { 165 Class sfInterface = SessionFactory.class; 166 if (target instanceof SessionFactoryImplementor) { 167 sfInterface = SessionFactoryImplementor.class; 168 } 169 return (SessionFactory) Proxy.newProxyInstance(sfInterface.getClassLoader(), 170 new Class [] {sfInterface}, new TransactionAwareInvocationHandler(target)); 171 } 172 173 177 protected final SessionFactory getSessionFactory() { 178 if (this.sessionFactory == null) { 179 throw new IllegalStateException ("SessionFactory not initialized yet"); 180 } 181 return this.sessionFactory; 182 } 183 184 187 public void destroy() throws HibernateException { 188 logger.info("Closing Hibernate SessionFactory"); 189 try { 190 beforeSessionFactoryDestruction(); 191 } 192 finally { 193 this.sessionFactory.close(); 194 } 195 } 196 197 198 201 public Object getObject() { 202 return this.sessionFactory; 203 } 204 205 public Class getObjectType() { 206 return (this.sessionFactory != null) ? this.sessionFactory.getClass() : SessionFactory.class; 207 } 208 209 public boolean isSingleton() { 210 return true; 211 } 212 213 214 222 public DataAccessException translateExceptionIfPossible(RuntimeException ex) { 223 if (ex instanceof HibernateException) { 224 return convertHibernateAccessException((HibernateException) ex); 225 } 226 return null; 227 } 228 229 239 protected DataAccessException convertHibernateAccessException(HibernateException ex) { 240 if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) { 241 JDBCException jdbcEx = (JDBCException) ex; 242 return this.jdbcExceptionTranslator.translate( 243 "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException()); 244 } 245 return SessionFactoryUtils.convertHibernateAccessException(ex); 246 } 247 248 249 255 protected abstract SessionFactory buildSessionFactory() throws Exception ; 256 257 264 protected void afterSessionFactoryCreation() throws Exception { 265 } 266 267 274 protected void beforeSessionFactoryDestruction() { 275 } 276 277 278 282 private static class TransactionAwareInvocationHandler implements InvocationHandler { 283 284 private final SessionFactory target; 285 286 public TransactionAwareInvocationHandler(SessionFactory target) { 287 this.target = target; 288 } 289 290 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 291 293 if (method.getName().equals("getCurrentSession")) { 294 try { 296 return SessionFactoryUtils.doGetSession((SessionFactory) proxy, false); 297 } 298 catch (IllegalStateException ex) { 299 throw new HibernateException(ex.getMessage()); 300 } 301 } 302 else if (method.getName().equals("equals")) { 303 return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE); 305 } 306 else if (method.getName().equals("hashCode")) { 307 return new Integer (hashCode()); 309 } 310 311 try { 313 return method.invoke(this.target, args); 314 } 315 catch (InvocationTargetException ex) { 316 throw ex.getTargetException(); 317 } 318 } 319 } 320 321 } 322 | Popular Tags |