2011-12-31 55 views
1

我使用Hibernate 3.6.9与Atomikos和Spring 3.1。在阅读Where does the @Transactional annotation belong?之后,我已经从所有DAO中删除了@Transactional注释,并且我只将它们留在了Service上。在任何DAO DB操作删除这些注释后,我收到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的交易,我怎么能使用Service之外的DAO?解决这个问题的唯一方法是在任何使用daos的层中启动transactionsy(Transactional with propagation requires_new)?但是,当使用DAO Transactional时,我遇到了懒惰初始化异常(事务在表示层之前关闭 - 尝试初始化实体字段)。

编辑:

我应该如何管理交易时,Spring MVC的控制器可以直接访问DAO?控制器应该交易吗?

我的问题也出现在登录过程中,因为spring安全使用dao(没有@Transactional),所以没有层开始事务?

将@Transactional添加到例如春季安全使用的daos解决了这个问题 - >当@Transactional一切正常时,但不能在没有这个注释的情况下使用db。但是,将@Transactional添加到某些DAO会带来一些问题,因为当spring mvc想要显示一些数据时,会出现延迟初始化异常,然后在dao中只有手动Hibernate.initialize工作(因为最后@Transactional在表示层之前关闭事务!)。

+0

我猜想问题在于您的服务上的@Transaction注释未考虑在内。 - 请使用transation注释发布其中一种服务方法,以及使用调用该方法的statment的方法以及启用事务注释支持的配置部分。 – Ralph 2011-12-31 13:20:35

+0

@Ralph我已经提出了我的问题。 – mmatloka 2011-12-31 13:42:04

回答

1

海事组织,你应该初始化对象的那些领域中是后来在DAO中在表示层中需要。

如果急于初始化这些对象对您来说感觉有些“脏”,您应该引入由您的服务层映射到的新表示层特定类(视图模型)(如果需要,它仍然有一个打开的事务来读取) 。

由于我没有Java背景,我不知道是否需要访问数据库的“spring security”。如果确实如此,则必须在相应的服务层上添加这些事务属性,正如您已经发现的那样。但是,我不认为你必须把事务属性放在DAO方法的周围,这往往是一个深层次的问题。

+0

解决lazili通过在dao中初始化这些字段来初始化异常还有另一个缺点 - 我们仍在处理分离的对象。我使用OpenSessionInViewFilter将会话范围扩展为表示层。 – mmatloka 2011-12-31 14:49:00

+0

您不应该尝试捕获异常,但要确保从服务层传回到表示层的对象包含所有必需的 - 因此已初始化的值。 – tobsen 2011-12-31 15:17:29

0

否,错误是告诉你配置一个JTA事务管理器:

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

选择最适合您的情况之一。

这个休眠论坛的问题可能是相关的,以及:

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 2011-12-31 13:24:36

+0

这个类的签名是否符合Spring的JTA?如果不是,它将如何使用?对不起,我对Atomikos不熟悉。看看Hibernate论坛的问题。它谈到了会议问题。 – duffymo 2011-12-31 13:26:28

+0

我已经延长了我的问题。 – mmatloka 2011-12-31 13:41:57