/// <summary> /// Execute the specified action assuming that the result object is a List. /// </summary> /// <remarks> /// This is a convenience method for executing Hibernate find calls or /// queries within an action. /// </remarks> /// <param name="action">The calback object that specifies the Hibernate action.</param> /// <returns>A IList returned by the action, or null /// </returns> /// <exception cref="DataAccessException">In case of Hibernate errors</exception> public IList ExecuteFind(IHibernateCallback action) { Object result = Execute(action, ExposeNativeSession); if (result != null && !(result is IList)) { throw new InvalidDataAccessApiUsageException( "Result object returned from HibernateCallback isn't a List: [" + result + "]"); } return (IList) result; }
/// <summary> /// Execute the action specified by the given action object within a Session. /// </summary> /// <param name="action">callback object that specifies the Hibernate action.</param> /// <param name="exposeNativeSession">if set to <c>true</c> expose the native hibernate session to /// callback code.</param> /// <returns> /// a result object returned by the action, or <code>null</code> /// </returns> public object Execute(IHibernateCallback action, bool exposeNativeSession) { ISession session = Session; bool existingTransaction = SessionFactoryUtils.IsSessionTransactional(session, SessionFactory); if (existingTransaction) { if (log.IsDebugEnabled) { log.Debug("Found thread-bound Session for HibernateTemplate"); } } FlushModeHolder previousFlushModeHolder = new FlushModeHolder(); try { previousFlushModeHolder = ApplyFlushMode(session, existingTransaction); ISession sessionToExpose = (exposeNativeSession ? session : CreateSessionProxy(session)); Object result = action.DoInHibernate(sessionToExpose); FlushIfNecessary(session, existingTransaction); return result; } catch (ADOException ex) { IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); if (dbProvider != null && dbProvider.IsDataAccessException(ex.InnerException)) { throw ConvertAdoAccessException(ex); } else { throw new HibernateSystemException(ex); } } catch (HibernateException ex) { throw ConvertHibernateAccessException(ex); } catch (Exception ex) { IDbProvider dbProvider = SessionFactoryUtils.GetDbProvider(SessionFactory); if (dbProvider != null && dbProvider.IsDataAccessException(ex)) { throw ConvertAdoAccessException(ex); } else { // Callback code throw application exception or other non DB related exception. throw; } } finally { if (existingTransaction) { if (log.IsDebugEnabled) { log.Debug("Not closing pre-bound Hibernate Session after HibernateTemplate"); } if (previousFlushModeHolder.ModeWasSet) { session.FlushMode = previousFlushModeHolder.Mode; } } else { // Never use deferred close for an explicitly new Session. if (AlwaysUseNewSession) { SessionFactoryUtils.CloseSession(session); } else { SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, SessionFactory); } } } }
/// <summary> /// Execute the action specified by the given action object within a Session. /// </summary> /// <param name="action">The callback object that specifies the Hibernate action.</param> /// <returns> /// a result object returned by the action, or <code>null</code> /// </returns> /// <remarks> /// Application exceptions thrown by the action object get propagated to the /// caller (can only be unchecked). Hibernate exceptions are transformed into /// appropriate DAO ones. Allows for returning a result object, i.e. a domain /// object or a collection of domain objects. /// <p>Note: Callback code is not supposed to handle transactions itself! /// Use an appropriate transaction manager like HibernateTransactionManager. /// Generally, callback code must not touch any Session lifecycle methods, /// like close, disconnect, or reconnect, to let the template do its work. /// </p> /// </remarks> /// <exception cref="DataAccessException">In case of Hibernate errors</exception> public object Execute(IHibernateCallback action) { return Execute(action, ExposeNativeSession); }