Click here to Skip to main content
15,880,956 members
Articles / Programming Languages / XML

Building a Middle Tier Component using NHibernate and Spring.NET

Rate me:
Please Sign up or sign in to vote.
4.50/5 (21 votes)
10 May 2006CPOL8 min read 158.2K   2.4K   109  
Building a highly pluggable middle-tier component with NHibernate and Spring.Net.
#region License

/*
 * Copyright � 2002-2005 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 System.Diagnostics;
using System.Reflection;
using NHibernate.Cfg;
using NHibernate;
using Spring.Objects.Factory;
using log4net;
using System.Collections;
using System.Collections.Specialized;
using Spring.Transaction.Support;
#endregion

namespace Spring.Orm.Hibernate
{
	 /// <summary>
	 /// Helper class featuring methods for Hibernate session handling,
	 /// allowing for reuse of Hibernate Session instances within transactions.
	 ///
	 /// <p>Note: Spring's Hibernate support requires Hibernate 1.1 (as of Spring 1.0).
	 ///
	 /// <author> Juergen Hoeller </author>
	 /// <author> Moim Hossan (.NET) </author>
	 /// </p>
	 /// </summary>
	public abstract class SessionFactoryUtils
	{
		private static ILog logger = LogManager.GetLogger( typeof(SessionFactoryUtils));

		/// <summary>
		/// Get a Hibernate Session for the given SessionFactory. Is aware of and will
		/// return any existing corresponding Session bound to the current thread, for
		/// example when using HibernateTransactionManager. Will create a new Session
		/// otherwise, if allowCreate is true.
		/// <p>This is the <code>getSession</code> method used by typical data access code,
		/// in combination with <code>CloseSessionIfNecessary</code> called when done with
		/// the Session. Note that HibernateTemplate allows to write data access code
		/// without caring about such resource handling.</p>
		/// @see HibernateTemplate
		/// </summary>
		public static ISession GetSession(ISessionFactory sessionFactory, bool allowCreate)
		{
			return GetSession( sessionFactory, null, true, allowCreate);
		}
		/// <summary>
		/// Get a Hibernate Session for the given SessionFactory. Is aware of and will
		/// return any existing corresponding Session bound to the current thread, for
		/// example when using HibernateTransactionManager. Will always create a new
		/// Session otherwise.
		/// </summary>
		public static ISession GetSession(ISessionFactory sessionFactory, IInterceptor entityInterceptor) 
		{
			return GetSession(sessionFactory, entityInterceptor, true);
		}
		/// <summary>
		/// Get a Hibernate Session for the given SessionFactory. Is aware of and will
		/// return any existing corresponding Session bound to the current thread, for
		/// example when using HibernateTransactionManager. Will always create a new
		/// Session otherwise.
		/// </summary>
		public static ISession GetSession(
			ISessionFactory sessionFactory, IInterceptor entityInterceptor, bool allowSynchronization)
		{
			return GetSession(sessionFactory, entityInterceptor, allowSynchronization, true);
		}
		/// <summary>
		/// Get Session
		/// </summary>
		/// <param name="sessionFactory"></param>
		/// <param name="entityInterceptor"></param>
		/// <param name="allowSynchronization"></param>
		/// <param name="allowCreate"></param>
		/// <returns></returns>
		private static ISession GetSession(ISessionFactory sessionFactory, 
			IInterceptor entityInterceptor, bool allowSynchronization, bool allowCreate)
		{
			System.Diagnostics.Trace.Assert( ( null != sessionFactory ) , "No SessionFactory specified");

			if( TransactionSyncManager.HasResource() )
			{
				SessionHolder sessionHolder = (SessionHolder) TransactionSyncManager.GetResource();

				if ( sessionHolder != null ) 
				{
					return sessionHolder.GetSession();	
				}
			}
//
//			SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResources(sessionFactory);
//
//			if ( sessionHolder != null && !sessionHolder.IsEmpty) 
//			{
//				return sessionHolder.GetSession();	
//			}

			if (!allowCreate) 
			{
				throw new ApplicationException("No Hibernate session bound to thread, " +
					"and configuration does not allow creation of new one here");
			}

			logger.Debug("Opening Hibernate session");

			return GetNewSession( sessionFactory , entityInterceptor );			
		}		
		/// <summary>
		/// Creates a nes Session.
		/// Disregarding if any session is already exists for the current thread.
		/// 
		/// Always create a new session
		/// </summary>
		/// <param name="sessionFactory">The Session Factory</param>
		/// <returns>The Session</returns>
		public static ISession GetNewSession(ISessionFactory sessionFactory) 
		{
			return GetNewSession(sessionFactory, null);
		}
		/// <summary>
		/// Creates a nes Session.
		/// Disregarding if any session is already exists for the current thread.
		/// 
		/// Always create a new session
		/// <param name="sessionFactory">The Session Factory</param>
		/// <param name="entityInterceptor">The Entity Interceptor</param>
		/// <returns>The Session</returns>
		public static ISession GetNewSession(ISessionFactory sessionFactory, IInterceptor entityInterceptor) 
		{
			// Check if the Session Factory is Empty
			System.Diagnostics.Trace.Assert( ( null != sessionFactory ) , "No SessionFactory specified");

			try 
			{
				return ( null == entityInterceptor ) ? 
					sessionFactory.OpenSession( ) : 
					sessionFactory.OpenSession( entityInterceptor );

//				SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.GetResources(sessionFactory);
//
//				if (sessionHolder != null && !sessionHolder.IsEmpty) 
//				{
//					if (entityInterceptor != null) 
//					{
//						return sessionFactory.OpenSession(sessionHolder.AnySession.Connection , entityInterceptor);
//					}
//					else 
//					{
//						return sessionFactory.OpenSession(sessionHolder.AnySession.Connection);
//					}
//				}
//				else 
//				{
//					if (entityInterceptor != null) 
//					{
//						return sessionFactory.OpenSession(entityInterceptor);
//					}
//					else 
//					{
//						return sessionFactory.OpenSession();
//					}
//				}
			}
			catch (Exception ex) 
			{
				// SQLException underneath
				throw new ApplicationException("Could not open Hibernate session", ex);
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="session"></param>
		/// <param name="sessionFactory"></param>
		public static void CloseSessionIfNecessary(ISession session, ISessionFactory sessionFactory) 
		{
			if (session == null) 
			{
				return;
			}
			// Only close non-transactional Sessions.
			if (!IsSessionTransactional(session, sessionFactory)) 
			{
				//closeSessionOrRegisterDeferredClose(session, sessionFactory); -- Moim
				DoClose( session );
			}			
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="session"></param>
		/// <param name="sessionFactory"></param>
		/// <returns></returns>
		public static bool IsSessionTransactional(ISession session, ISessionFactory sessionFactory) 
		{
			if( TransactionSyncManager.HasResource() )
			{
				SessionHolder holder = TransactionSyncManager.GetResource() as SessionHolder;

				if( holder.ContainSession( session ))
				{
					return true;	// Yes this session has created through the transaction manager
									// And It may has transactions.
				}
			}
			// No Transaction has found for this thread-bound.
			// so user may be created this session by his own hand
			return false;

//			SessionHolder sessionHolder =
//				(SessionHolder) TransactionSynchronizationManager.GetResources(sessionFactory);
//
//			return (sessionHolder != null && sessionHolder.ContainSession(session));
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="session"></param>
		private static void DoClose(ISession session) 
		{
			logger.Debug("Closing Hibernate session");
			try 
			{
				session.Close();
			}
			
			catch (Exception ex) 
			{
				logger.Error("Could not close Hibernate session", ex);
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Netherlands Netherlands
Engineer Powered by the Cloud

Comments and Discussions