Как привязать сессию NHibernate к запросу (ASP.NET) используя Spring.NET - CodeHelper

Как привязать сессию NHibernate к запросу (ASP.NET) используя Spring.NET

1

Как сделать так, чтобы сессия NHibernate открывалась при начале запроса к веб-приложению и закрывалась, когда запрос обработан (паттерн OpenSessionInView). NHibernate работает в связке со Spring.NET.

Лучший ответ:

1

Нужно объявить в Web.config модуль OpenSessionInViewModule:

<httpModules>
    <!-- ... -->
    <add name="OpenSessionInView" type="Spring.Data.NHibernate.Support.OpenSessionInViewModule, Spring.Data.NHibernateXXX"/>
    <!-- ... -->
</httpModules>

Вместо NHibernateXXX пишется актуальная версия NHibernate (например, Spring.Data.NHibernate20 для версии 2.0). Следует помнить, что сессия, которая открывается в начале запроса настроена только на чтение (FlushMode.NEVER) и если попытаться выполнить код типа:

public virtual void UpdateOrInsert(Entity entity)
{
    HibernateTemplate.SaveOrUpdate(entity);
}

то получим исключение:

Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition

Есть два выхода из этой ситуации:

Установить FlushMode равное AUTO. Но так лучше не делать, потому что в этом случае результаты будут коммититься в базу уже после того, как пользователю вернулся ответ. То есть пользователя невозможно будет уведомить о результате операции.

Обернуть вызов метода DAO в транзакцию. Это можно сделать на уровне слоя доступа к данным или на уровне сервисов, декларативно или программно. Легче всего пометить метод репозитория атрибутом Transaction:

[Transaction(ReadOnly = false)]
public virtual void UpdateOrInsert(Entity entity)
{
    HibernateTemplate.SaveOrUpdate(entity);
}

Чтобы этот вариант заработал нужно включить строку импорта aop-объектов для автоматического распознования объектов с транзакциями:

<tx:attribute-driven transaction-manager="transactionManager"/>

или написать этот xml вручную:

<!-- The rest of the config file is common no matter how many objects you add -->
<!-- that you would like to have declarative tx management applied to -->

<object id="autoProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop">
</object>

<object id="transactionAdvisor" type="Spring.Transaction.Interceptor.TransactionAttributeSourceAdvisor, Spring.Data">
    <property name="TransactionInterceptor" ref="transactionInterceptor"/>
</object>

<!-- Transaction Interceptor -->
<object id="transactionInterceptor" type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
    <property name="TransactionManager" ref="transactionManager"/>
    <property name="TransactionAttributeSource" ref="attributeTransactionAttributeSource"/>
</object>

<object id="attributeTransactionAttributeSource" type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data">
</object>
v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.