2011-12-31 3 views
1

Я использую Hibernate 3.6.9 с Atomikos и Spring 3.1. После прочтения Where does the @Transactional annotation belong? Я удалил аннотации @Transactional из всех DAO, и я оставил их только на службе. После удаления этих аннотаций на любой операции дао дб я получаюИспользование транзакций в DAO

org.hibernate.HibernateException: Unable to locate current JTA transaction 

Моя конфигурация:

<tx:annotation-driven transaction-manager="jtaTransactionManager" /> 


    <!-- Configure the Spring framework to use JTA transactions from Atomikos --> 
    <bean id="jtaTransactionManager" 
     class="org.springframework.transaction.jta.JtaTransactionManager"> 
     <property name="transactionManager" ref="atomikosTransactionManager" /> 
     <property name="userTransaction" ref="atomikosUserTransaction" /> 
    </bean> 

    <!-- Construct Atomikos UserTransactionManager, needed to configure Spring --> 
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" 
     init-method="init" destroy-method="close"> 

     <!-- when close is called, should we force transactions to terminate or 
      not? --> 
     <property name="forceShutdown" value="false" /> 
    </bean> 

    <!-- Also use Atomikos UserTransactionImp, needed to configure Spring --> 
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 

     <property name="transactionTimeout" value="300" /> 
    </bean> 

сессии Свойства фабрики:

   <prop key="hibernate.connection.isolation">3</prop> 
       <prop key="hibernate.current_session_context_class">jta</prop> 
       <prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory 
       </prop> 
       <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 
       </prop> 

Как следует управлять сделок DAO, и как я могу использовать DAO за пределами Сервиса? Единственный способ решить эту проблему для запуска транзакций вручную (Transactional с распространением require_new) на любом уровне, использующем daos? Однако при использовании Transactional с DAO я столкнулся с проблемами с ленивыми исключениями инициализации (транзакция закрыта до уровня представления - пытается инициализировать поля объекта).

Edit:

Как я должен управлять транзакциями, когда контроллер Spring MVC может получить доступ непосредственно DAO? Должен ли контроллер быть транзакционным?

Моя проблема также появляется во время процесса входа в систему, поскольку весенняя безопасность использует dao (без @Transactional), поэтому ни один уровень не начинает транзакцию?

Добавление @Transactional, например. daos, используемый весной безопасности, решает проблему -> когда есть @Transactional, все работает, но невозможно использовать db без этих аннотаций. Но добавление @Transactional к некоторым DAO приводит к проблемам, потому что когда весна mvc хочет отобразить некоторые данные, появляется ленивое исключение инициализации, а затем работает только ручной Hibernate.initialize в dao (потому что последний @Transactional закрывает транзакцию перед слоем представления!).

+0

Я думаю, проблема в том, что @Transaction Annotation на ваши услуги не учитывается. - Пожалуйста, разместите один из методов обслуживания с аннотацией трансации, а также метод со статусом, который вызывает метод и часть конфигурации, которая позволяет поддерживать транзакционную аннотацию. – Ralph

+0

@Ralph Я расширил свой вопрос. – mmatloka

ответ

1

ИМО, вы должны инициализировать эти поля объектов в DAO, которые позже необходимых в слое презентации.

Если вы хотите, чтобы эти объекты чувствовали себя несколько «грязными», вам следует ввести новые классы уровня представления (модель просмотра), которые отображаются на вашем уровне обслуживания (который по-прежнему имеет открытую транзакцию для чтения, если необходимо) ,

Поскольку у меня нет фона Java, я не знаю, нужна ли «весенняя безопасность» для доступа к базе данных. Если это так, вы также должны добавить эти транзакционные атрибуты на соответствующем servicelayer, как вы уже узнали. Тем не менее, я не думаю, что вы обязательно должны поместить транзакционные атрибуты вокруг методов DAO, которые часто являются одним уровнем до глубины.

+0

Устранение исключения инициализации lazili путем инициализации этих полей в dao также имеет еще один недостаток - мы все еще работаем над отдельными объектами. Я рассматриваю расширение области сеанса до уровня представления с помощью OpenSessionInViewFilter. – mmatloka

+0

вы не должны пытаться поймать исключение, но убедитесь, что объекты, переданные с вашего уровня обслуживания на уровень представления, содержат все необходимые и, следовательно, инициализированные значения. – tobsen

0

Нет, ошибка говорит вам настроить менеджер транзакций JTA:

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/transaction/jta/JtaTransactionManager.html

Выберите тот, который лучше работает для вашей ситуации.

Этот Hibernate форум вопрос может быть уместен, а также:

https://forum.hibernate.org/viewtopic.php?p=2430788

Контроллеры должны не быть транзакционными. У вас есть они в нужном месте - они принадлежат сервисам.

OpenSessionInView может быть ваше решение:

http://springtips.blogspot.com/2007/07/open-session-in-view.html

Или это не может:

Why is Hibernate Open Session in View considered a bad practice?

+0

Я настроил диспетчер транзакций JTA, как описано в документации atomikos. – mmatloka

+0

Подписывается ли подпись класса в JTA Spring? Если нет, как он будет использоваться? Извините, я не знаком с Atomikos. Проверьте этот вопрос форума Hibernate. В нем говорилось о проблемах сессии. – duffymo

+0

Я расширил свой вопрос. – mmatloka

Смежные вопросы