001/* 002 * Copyright 2002-2015 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.hibernate5.support; 018 019import org.hibernate.Session; 020import org.hibernate.SessionFactory; 021 022import org.springframework.dao.DataAccessResourceFailureException; 023import org.springframework.dao.support.DaoSupport; 024import org.springframework.orm.hibernate5.HibernateTemplate; 025 026/** 027 * Convenient super class for Hibernate-based data access objects. 028 * 029 * <p>Requires a {@link SessionFactory} to be set, providing a 030 * {@link org.springframework.orm.hibernate5.HibernateTemplate} based on it to 031 * subclasses through the {@link #getHibernateTemplate()} method. 032 * Can alternatively be initialized directly with a HibernateTemplate, 033 * in order to reuse the latter's settings such as the SessionFactory, 034 * exception translator, flush mode, etc. 035 * 036 * <p>This class will create its own HibernateTemplate instance if a SessionFactory 037 * is passed in. The "allowCreate" flag on that HibernateTemplate will be "true" 038 * by default. A custom HibernateTemplate instance can be used through overriding 039 * {@link #createHibernateTemplate}. 040 * 041 * <p><b>NOTE: Hibernate access code can also be coded in plain Hibernate style. 042 * Hence, for newly started projects, consider adopting the standard Hibernate 043 * style of coding data access objects instead, based on 044 * {@link SessionFactory#getCurrentSession()}. 045 * This HibernateTemplate primarily exists as a migration helper for Hibernate 3 046 * based data access code, to benefit from bug fixes in Hibernate 5.x.</b> 047 * 048 * @author Juergen Hoeller 049 * @since 4.2 050 * @see #setSessionFactory 051 * @see #getHibernateTemplate 052 * @see org.springframework.orm.hibernate5.HibernateTemplate 053 */ 054public abstract class HibernateDaoSupport extends DaoSupport { 055 056 private HibernateTemplate hibernateTemplate; 057 058 059 /** 060 * Set the Hibernate SessionFactory to be used by this DAO. 061 * Will automatically create a HibernateTemplate for the given SessionFactory. 062 * @see #createHibernateTemplate 063 * @see #setHibernateTemplate 064 */ 065 public final void setSessionFactory(SessionFactory sessionFactory) { 066 if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) { 067 this.hibernateTemplate = createHibernateTemplate(sessionFactory); 068 } 069 } 070 071 /** 072 * Create a HibernateTemplate for the given SessionFactory. 073 * Only invoked if populating the DAO with a SessionFactory reference! 074 * <p>Can be overridden in subclasses to provide a HibernateTemplate instance 075 * with different configuration, or a custom HibernateTemplate subclass. 076 * @param sessionFactory the Hibernate SessionFactory to create a HibernateTemplate for 077 * @return the new HibernateTemplate instance 078 * @see #setSessionFactory 079 */ 080 protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) { 081 return new HibernateTemplate(sessionFactory); 082 } 083 084 /** 085 * Return the Hibernate SessionFactory used by this DAO. 086 */ 087 public final SessionFactory getSessionFactory() { 088 return (this.hibernateTemplate != null ? this.hibernateTemplate.getSessionFactory() : null); 089 } 090 091 /** 092 * Set the HibernateTemplate for this DAO explicitly, 093 * as an alternative to specifying a SessionFactory. 094 * @see #setSessionFactory 095 */ 096 public final void setHibernateTemplate(HibernateTemplate hibernateTemplate) { 097 this.hibernateTemplate = hibernateTemplate; 098 } 099 100 /** 101 * Return the HibernateTemplate for this DAO, 102 * pre-initialized with the SessionFactory or set explicitly. 103 * <p><b>Note: The returned HibernateTemplate is a shared instance.</b> 104 * You may introspect its configuration, but not modify the configuration 105 * (other than from within an {@link #initDao} implementation). 106 * Consider creating a custom HibernateTemplate instance via 107 * {@code new HibernateTemplate(getSessionFactory())}, in which case 108 * you're allowed to customize the settings on the resulting instance. 109 */ 110 public final HibernateTemplate getHibernateTemplate() { 111 return this.hibernateTemplate; 112 } 113 114 @Override 115 protected final void checkDaoConfig() { 116 if (this.hibernateTemplate == null) { 117 throw new IllegalArgumentException("'sessionFactory' or 'hibernateTemplate' is required"); 118 } 119 } 120 121 122 /** 123 * Conveniently obtain the current Hibernate Session. 124 * @return the Hibernate Session 125 * @throws DataAccessResourceFailureException if the Session couldn't be created 126 * @see SessionFactory#getCurrentSession() 127 */ 128 protected final Session currentSession() throws DataAccessResourceFailureException { 129 return getSessionFactory().getCurrentSession(); 130 } 131 132}