001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.orm.hibernate3.support;
018
019import org.hibernate.HibernateException;
020import org.hibernate.Session;
021import org.hibernate.SessionFactory;
022
023import org.springframework.dao.DataAccessException;
024import org.springframework.dao.DataAccessResourceFailureException;
025import org.springframework.dao.support.DaoSupport;
026
027/**
028 * Convenient super class for Hibernate-based data access objects.
029 *
030 * <p>Requires a {@link org.hibernate.SessionFactory} to be set, providing a
031 * {@link org.springframework.orm.hibernate3.HibernateTemplate} based on it to
032 * subclasses through the {@link #getHibernateTemplate()} method.
033 * Can alternatively be initialized directly with a HibernateTemplate,
034 * in order to reuse the latter's settings such as the SessionFactory,
035 * exception translator, flush mode, etc.
036 *
037 * <p>This base class is mainly intended for HibernateTemplate usage but can
038 * also be used when working with a Hibernate Session directly, for example
039 * when relying on transactional Sessions. Convenience {@link #getSession}
040 * and {@link #releaseSession} methods are provided for that usage style.
041 *
042 * <p>This class will create its own HibernateTemplate instance if a SessionFactory
043 * is passed in. The "allowCreate" flag on that HibernateTemplate will be "true"
044 * by default. A custom HibernateTemplate instance can be used through overriding
045 * {@link #createHibernateTemplate}.
046 *
047 * <p><b>NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can
048 * also be coded in plain Hibernate style. Hence, for newly started projects,
049 * consider adopting the standard Hibernate3 style of coding data access objects
050 * instead, based on {@link org.hibernate.SessionFactory#getCurrentSession()}.</b>
051 *
052 * @author Juergen Hoeller
053 * @since 1.2
054 * @see #setSessionFactory
055 * @see #getHibernateTemplate
056 * @see org.springframework.orm.hibernate3.HibernateTemplate
057 * @deprecated as of Spring 4.3, in favor of Hibernate 4.x/5.x
058 */
059@Deprecated
060public abstract class HibernateDaoSupport extends DaoSupport {
061
062        private org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate;
063
064
065        /**
066         * Set the Hibernate SessionFactory to be used by this DAO.
067         * Will automatically create a HibernateTemplate for the given SessionFactory.
068         * @see #createHibernateTemplate
069         * @see #setHibernateTemplate
070         */
071        public final void setSessionFactory(SessionFactory sessionFactory) {
072                if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
073                        this.hibernateTemplate = createHibernateTemplate(sessionFactory);
074                }
075        }
076
077        /**
078         * Create a HibernateTemplate for the given SessionFactory.
079         * Only invoked if populating the DAO with a SessionFactory reference!
080         * <p>Can be overridden in subclasses to provide a HibernateTemplate instance
081         * with different configuration, or a custom HibernateTemplate subclass.
082         * @param sessionFactory the Hibernate SessionFactory to create a HibernateTemplate for
083         * @return the new HibernateTemplate instance
084         * @see #setSessionFactory
085         */
086        protected org.springframework.orm.hibernate3.HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
087                return new org.springframework.orm.hibernate3.HibernateTemplate(sessionFactory);
088        }
089
090        /**
091         * Return the Hibernate SessionFactory used by this DAO.
092         */
093        public final SessionFactory getSessionFactory() {
094                return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null);
095        }
096
097        /**
098         * Set the HibernateTemplate for this DAO explicitly,
099         * as an alternative to specifying a SessionFactory.
100         * @see #setSessionFactory
101         */
102        public final void setHibernateTemplate(org.springframework.orm.hibernate3.HibernateTemplate hibernateTemplate) {
103                this.hibernateTemplate = hibernateTemplate;
104        }
105
106        /**
107         * Return the HibernateTemplate for this DAO,
108         * pre-initialized with the SessionFactory or set explicitly.
109         * <p><b>Note: The returned HibernateTemplate is a shared instance.</b>
110         * You may introspect its configuration, but not modify the configuration
111         * (other than from within an {@link #initDao} implementation).
112         * Consider creating a custom HibernateTemplate instance via
113         * {@code new HibernateTemplate(getSessionFactory())}, in which case
114         * you're allowed to customize the settings on the resulting instance.
115         */
116        public final org.springframework.orm.hibernate3.HibernateTemplate getHibernateTemplate() {
117          return this.hibernateTemplate;
118        }
119
120        @Override
121        protected final void checkDaoConfig() {
122                if (this.hibernateTemplate == null) {
123                        throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required");
124                }
125        }
126
127
128        /**
129         * Obtain a Hibernate Session, either from the current transaction or
130         * a new one. The latter is only allowed if the
131         * {@link org.springframework.orm.hibernate3.HibernateTemplate#setAllowCreate "allowCreate"}
132         * setting of this bean's {@link #setHibernateTemplate HibernateTemplate} is "true".
133         * <p><b>Note that this is not meant to be invoked from HibernateTemplate code
134         * but rather just in plain Hibernate code.</b> Either rely on a thread-bound
135         * Session or use it in combination with {@link #releaseSession}.
136         * <p>In general, it is recommended to use HibernateTemplate, either with
137         * the provided convenience operations or with a custom HibernateCallback
138         * that provides you with a Session to work on. HibernateTemplate will care
139         * for all resource management and for proper exception conversion.
140         * @return the Hibernate Session
141         * @throws DataAccessResourceFailureException if the Session couldn't be created
142         * @throws IllegalStateException if no thread-bound Session found and allowCreate=false
143         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean)
144         * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage
145         */
146        @Deprecated
147        protected final Session getSession() throws DataAccessResourceFailureException, IllegalStateException {
148                return getSession(this.hibernateTemplate.isAllowCreate());
149        }
150
151        /**
152         * Obtain a Hibernate Session, either from the current transaction or
153         * a new one. The latter is only allowed if "allowCreate" is true.
154         * <p><b>Note that this is not meant to be invoked from HibernateTemplate code
155         * but rather just in plain Hibernate code.</b> Either rely on a thread-bound
156         * Session or use it in combination with {@link #releaseSession}.
157         * <p>In general, it is recommended to use
158         * {@link #getHibernateTemplate() HibernateTemplate}, either with
159         * the provided convenience operations or with a custom
160         * {@link org.springframework.orm.hibernate3.HibernateCallback} that
161         * provides you with a Session to work on. HibernateTemplate will care
162         * for all resource management and for proper exception conversion.
163         * @param allowCreate if a non-transactional Session should be created when no
164         * transactional Session can be found for the current thread
165         * @return the Hibernate Session
166         * @throws DataAccessResourceFailureException if the Session couldn't be created
167         * @throws IllegalStateException if no thread-bound Session found and allowCreate=false
168         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean)
169         * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage
170         */
171        @Deprecated
172        protected final Session getSession(boolean allowCreate)
173                        throws DataAccessResourceFailureException, IllegalStateException {
174
175                return (!allowCreate ?
176                                org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(getSessionFactory(), false) :
177                                org.springframework.orm.hibernate3.SessionFactoryUtils.getSession(
178                                                getSessionFactory(),
179                                                this.hibernateTemplate.getEntityInterceptor(),
180                                                this.hibernateTemplate.getJdbcExceptionTranslator()));
181        }
182
183        /**
184         * Convert the given HibernateException to an appropriate exception from the
185         * {@code org.springframework.dao} hierarchy. Will automatically detect
186         * wrapped SQLExceptions and convert them accordingly.
187         * <p>Delegates to the
188         * {@link org.springframework.orm.hibernate3.HibernateTemplate#convertHibernateAccessException}
189         * method of this DAO's HibernateTemplate.
190         * <p>Typically used in plain Hibernate code, in combination with
191         * {@link #getSession} and {@link #releaseSession}.
192         * @param ex HibernateException that occurred
193         * @return the corresponding DataAccessException instance
194         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#convertHibernateAccessException
195         * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage
196         */
197        @Deprecated
198        protected final DataAccessException convertHibernateAccessException(HibernateException ex) {
199                return this.hibernateTemplate.convertHibernateAccessException(ex);
200        }
201
202        /**
203         * Close the given Hibernate Session, created via this DAO's SessionFactory,
204         * if it isn't bound to the thread (i.e. isn't a transactional Session).
205         * <p>Typically used in plain Hibernate code, in combination with
206         * {@link #getSession} and {@link #convertHibernateAccessException}.
207         * @param session the Session to close
208         * @see org.springframework.orm.hibernate3.SessionFactoryUtils#releaseSession
209         * @deprecated as of Spring 3.2.7, in favor of {@link org.springframework.orm.hibernate3.HibernateTemplate} usage
210         */
211        @Deprecated
212        protected final void releaseSession(Session session) {
213                org.springframework.orm.hibernate3.SessionFactoryUtils.releaseSession(session, getSessionFactory());
214        }
215
216}