#region License
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#region Imports
using System;
using NHibernate;
using Spring.Dao;
using Spring.Dao.Support;
#endregion
namespace Spring.Data.NHibernate.Generic.Support{
/// <summary>
/// Convenient super class for Hibernate data access objects.
/// </summary>
/// <remarks>
/// <para>Requires a SessionFactory to be set, providing a HibernateTemplate
/// based on it to subclasses. Can alternatively be initialized directly with
/// a HibernateTemplate, to reuse the latter's settings such as the SessionFactory,
/// exception translator, flush mode, etc
/// </para>
/// This base call is mainly intended for HibernateTemplate usage.
/// <para>
/// This class will create its own HibernateTemplate if only a SessionFactory
/// is passed in. The "allowCreate" flag on that HibernateTemplate will be "true"
/// by default. A custom HibernateTemplate instance can be used through overriding
/// <code>CreateHibernateTemplate</code>.
/// </para>
/// </remarks>
/// <author>Sree Nivask (.NET)</author>
/// <author>Mark Pollack (.NET)</author>
public abstract class HibernateDaoSupport : DaoSupport
{
#region Fields
private HibernateTemplate hibernateTemplate;
#endregion
#region Constructor (s)
/// <summary>
/// Initializes a new instance of the <see cref="HibernateDaoSupport"/> class.
/// </summary>
public HibernateDaoSupport()
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the hibernate template.
/// </summary>
/// <remarks>Set the HibernateTemplate for this DAO explicitly,
/// as an alternative to specifying a SessionFactory.
/// </remarks>
/// <value>The hibernate template.</value>
public HibernateTemplate HibernateTemplate
{
get
{
return hibernateTemplate;
}
set
{
hibernateTemplate = value;
}
}
/// <summary>
/// Gets or sets the session factory to be used by this DAO.
/// Will automatically create a HibernateTemplate for the given SessionFactory.
/// </summary>
/// <value>The session factory.</value>
public ISessionFactory SessionFactory
{
get
{
return (this.hibernateTemplate != null ? this.hibernateTemplate.SessionFactory : null);
}
set
{
hibernateTemplate = CreateHibernateTemplate(value);
}
}
/// <summary>
/// Get a Hibernate Session, either from the current transaction or a new one.
/// The latter is only allowed if the "allowCreate" setting of this object's
/// HibernateTemplate is true.
/// </summary>
/// <remarks>
/// <p><b>Note that this is not meant to be invoked from HibernateTemplate code
/// but rather just in plain Hibernate code.</b> Use it in combination with
/// <b>ReleaseSession</b>.
/// </p>
/// <p>In general, it is recommended to use HibernateTemplate, either with
/// the provided convenience operations or with a custom HibernateCallback
/// that provides you with a Session to work on. HibernateTemplate will care
/// for all resource management and for proper exception conversion.
/// </p>
/// </remarks>
/// <value>The Hibernate session.</value>
public ISession Session
{
get
{
return DoGetSession(HibernateTemplate.AllowCreate);
}
}
#endregion
#region Methods
/// <summary>
/// Create a HibernateTemplate for the given ISessionFactory.
/// </summary>
/// <remarks>
/// Only invoked if populating the DAO with a ISessionFactory reference!
/// <p>Can be overridden in subclasses to provide a HibernateTemplate instance
/// with different configuration, or a custom HibernateTemplate subclass.
/// </p>
/// </remarks>
/// <returns>The new HibernateTemplate instance</returns>
protected virtual HibernateTemplate CreateHibernateTemplate(ISessionFactory sessionFactory)
{
return new HibernateTemplate(sessionFactory);
}
/// <summary>
/// Check if the hibernate template property has been set.
/// </summary>
/// <exception cref="ArgumentException">If HibernateTemplate property is null.</exception>
protected override void CheckDaoConfig()
{
if (this.hibernateTemplate == null)
{
throw new ArgumentException("sessionFactory or hibernateTemplate is required");
}
}
/// <summary>
/// Get a Hibernate Session, either from the current transaction or
/// a new one. The latter is only allowed if "allowCreate" is true.
/// </summary>
/// <remarks>Note that this is not meant to be invoked from HibernateTemplate code
/// but rather just in plain Hibernate code. Either rely on a thread-bound
/// Session (via HibernateInterceptor), or use it in combination with
/// ReleaseSession.
/// <para>
/// In general, it is recommended to use HibernateTemplate, either with
/// the provided convenience operations or with a custom HibernateCallback
/// that provides you with a Session to work on. HibernateTemplate will care
/// for all resource management and for proper exception conversion.
/// </para>
/// </remarks>
/// <param name="allowCreate"> if a non-transactional Session should be created when no
/// transactional Session can be found for the current thread
/// </param>
/// <returns>Hibernate session.</returns>
/// <exception cref="DataAccessResourceFailureException">
/// If the Session couldn't be created
/// </exception>
/// <exception cref="InvalidOperationException">
/// if no thread-bound Session found and allowCreate false
/// </exception>
/// <seealso cref="ReleaseSession"/>
protected ISession DoGetSession(bool allowCreate)
{
return (!allowCreate ?
SessionFactoryUtils.GetSession(SessionFactory, false) :
SessionFactoryUtils.GetSession(
SessionFactory,
this.hibernateTemplate.EntityInterceptor,
this.hibernateTemplate.AdoExceptionTranslator));
}
/// <summary>
/// Convert the given HibernateException to an appropriate exception from the
/// <code>org.springframework.dao</code> hierarchy. Will automatically detect
/// wrapped ADO.NET Exceptions and convert them accordingly.
/// </summary>
/// <param name="ex">HibernateException that occured.</param>
/// <returns>
/// The corresponding DataAccessException instance
/// </returns>
/// <remarks>
/// The default implementation delegates to SessionFactoryUtils
/// and convertAdoAccessException. Can be overridden in subclasses.
/// </remarks>
protected DataAccessException ConvertHibernateAccessException(HibernateException ex)
{
return hibernateTemplate.ConvertHibernateAccessException(ex);
}
/// <summary>
/// Close the given Hibernate Session, created via this DAO's SessionFactory,
/// if it isn't bound to the thread.
/// </summary>
/// <remarks>
/// Typically used in plain Hibernate code, in combination with the
/// Session property and ConvertHibernateAccessException.
/// </remarks>
/// <param name="session">The session to close.</param>
protected void ReleaseSession(ISession session)
{
SessionFactoryUtils.ReleaseSession(session, SessionFactory);
}
#endregion
}
}
|