1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.orm.hibernate.support;
  17. import net.sf.hibernate.HibernateException;
  18. import net.sf.hibernate.Session;
  19. import net.sf.hibernate.SessionFactory;
  20. import org.apache.commons.logging.Log;
  21. import org.apache.commons.logging.LogFactory;
  22. import org.springframework.beans.factory.InitializingBean;
  23. import org.springframework.dao.CleanupFailureDataAccessException;
  24. import org.springframework.dao.DataAccessException;
  25. import org.springframework.dao.DataAccessResourceFailureException;
  26. import org.springframework.orm.hibernate.HibernateTemplate;
  27. import org.springframework.orm.hibernate.SessionFactoryUtils;
  28. /**
  29. * Convenient super class for Hibernate data access objects.
  30. *
  31. * <p>Requires a SessionFactory to be set, providing a HibernateTemplate
  32. * based on it to subclasses. Can alternatively be initialized directly via a
  33. * HibernateTemplate, to reuse the latter's settings like SessionFactory,
  34. * flush mode, exception translator, etc.
  35. *
  36. * <p>This base class is mainly intended for HibernateTemplate usage
  37. * but can also be used when working with SessionFactoryUtils directly,
  38. * e.g. in combination with HibernateInterceptor-managed Sessions.
  39. * Convenience getSession and closeSessionIfNecessary methods are provided
  40. * for that usage.
  41. *
  42. * @author Juergen Hoeller
  43. * @since 28.07.2003
  44. * @see #setSessionFactory
  45. * @see #setHibernateTemplate
  46. * @see org.springframework.orm.hibernate.HibernateTemplate
  47. * @see org.springframework.orm.hibernate.HibernateInterceptor
  48. */
  49. public abstract class HibernateDaoSupport implements InitializingBean {
  50. protected final Log logger = LogFactory.getLog(getClass());
  51. private HibernateTemplate hibernateTemplate;
  52. /**
  53. * Set the Hibernate SessionFactory to be used by this DAO.
  54. */
  55. public final void setSessionFactory(SessionFactory sessionFactory) {
  56. this.hibernateTemplate = new HibernateTemplate(sessionFactory);
  57. }
  58. /**
  59. * Return the Hibernate SessionFactory used by this DAO.
  60. */
  61. public final SessionFactory getSessionFactory() {
  62. return hibernateTemplate.getSessionFactory();
  63. }
  64. /**
  65. * Set the HibernateTemplate for this DAO explicitly,
  66. * as an alternative to specifying a SessionFactory.
  67. */
  68. public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
  69. this.hibernateTemplate = hibernateTemplate;
  70. }
  71. /**
  72. * Return the HibernateTemplate for this DAO,
  73. * pre-initialized with the SessionFactory or set explicitly.
  74. */
  75. public final HibernateTemplate getHibernateTemplate() {
  76. return hibernateTemplate;
  77. }
  78. public final void afterPropertiesSet() throws Exception {
  79. if (this.hibernateTemplate == null) {
  80. throw new IllegalArgumentException("sessionFactory or hibernateTemplate is required");
  81. }
  82. initDao();
  83. }
  84. /**
  85. * Subclasses can override this for custom initialization behavior.
  86. * Gets called after population of this instance's bean properties.
  87. * @throws Exception if initialization fails
  88. */
  89. protected void initDao() throws Exception {
  90. }
  91. /**
  92. * Get a Hibernate Session, either from the current transaction or
  93. * a new one. The latter is only allowed if the "allowCreate" setting
  94. * of this bean's HibernateTemplate is true.
  95. * @return the Hibernate Session
  96. * @throws DataAccessResourceFailureException if the Session couldn't be created
  97. * @throws IllegalStateException if no thread-bound Session found and allowCreate false
  98. * @see org.springframework.orm.hibernate.HibernateTemplate
  99. */
  100. protected final Session getSession()
  101. throws DataAccessResourceFailureException, IllegalStateException {
  102. return getSession(this.hibernateTemplate.isAllowCreate());
  103. }
  104. /**
  105. * Get a Hibernate Session, either from the current transaction or
  106. * a new one. The latter is only allowed if "allowCreate" is true.
  107. * @param allowCreate if a new Session should be created if no thread-bound found
  108. * @return the Hibernate Session
  109. * @throws DataAccessResourceFailureException if the Session couldn't be created
  110. * @throws IllegalStateException if no thread-bound Session found and allowCreate false
  111. * @see org.springframework.orm.hibernate.SessionFactoryUtils#getSession(SessionFactory, boolean)
  112. */
  113. protected final Session getSession(boolean allowCreate)
  114. throws DataAccessResourceFailureException, IllegalStateException {
  115. return (!allowCreate ?
  116. SessionFactoryUtils.getSession(getSessionFactory(), false) :
  117. SessionFactoryUtils.getSession(getSessionFactory(),
  118. this.hibernateTemplate.getEntityInterceptor(),
  119. this.hibernateTemplate.getJdbcExceptionTranslator()));
  120. }
  121. /**
  122. * Convert the given HibernateException to an appropriate exception from
  123. * the org.springframework.dao hierarchy. Will automatically detect
  124. * wrapped SQLExceptions and convert them accordingly.
  125. * <p>Delegates to the convertHibernateAccessException method of this
  126. * DAO's HibernateTemplate.
  127. * @param ex HibernateException that occured
  128. * @return the corresponding DataAccessException instance
  129. * @see #setHibernateTemplate
  130. * @see org.springframework.orm.hibernate.HibernateTemplate#convertHibernateAccessException
  131. */
  132. protected final DataAccessException convertHibernateAccessException(HibernateException ex) {
  133. return this.hibernateTemplate.convertHibernateAccessException(ex);
  134. }
  135. /**
  136. * Close the given Hibernate Session if necessary, created via this bean's
  137. * SessionFactory, if it isn't bound to the thread.
  138. * @param session Session to close
  139. * @throws DataAccessResourceFailureException if the Session couldn't be closed
  140. * @see org.springframework.orm.hibernate.SessionFactoryUtils#closeSessionIfNecessary
  141. */
  142. protected final void closeSessionIfNecessary(Session session)
  143. throws CleanupFailureDataAccessException {
  144. SessionFactoryUtils.closeSessionIfNecessary(session, getSessionFactory());
  145. }
  146. }