【问题标题】:No Session found for current thread using JTA TransactionManager使用 JTA TransactionManager 未找到当前线程的会话
【发布时间】:2012-06-05 21:09:08
【问题描述】:

我在使用 JTA 事务管理器时迁移到休眠 4 时遇到了一些问题。
也许你可以帮忙,因为我完全没有想法。

软件:

春季:3.1.1.RELEASE
休眠:4.1.3.Final
数据库:Oracle 11g
应用:Ejb 3.0部署在Websphere Application Server 7.0中(使用@Interceptors(SpringBeanAutowiringInterceptor.class)初始化spring上下文)

弹簧配置:

<context:annotation-config />
<context:component-scan base-package="myServicePackage,myDaoPackage" />

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/MyDataSource" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="myModelPackage" />
    <property name="mappingResources" value="queries.xml" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
        </props>
    </property>
</bean>

<tx:jta-transaction-manager />
<!-- <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" /> -->
<tx:annotation-driven />

服务:

@Service
public class TradeService {
    @Autowired
    private TradeDao tradeDao;
}

道:

@Repository
@Transactional
public class TradeDao {
    @Autowired
    private SessionFactory sessionFactory;

    public Trade getTrade(){
        return (Trade) sessionFactory.getCurrentSession().getNamedQuery("get_trade").uniqueResult();
    }

投掷:

org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)
at myDaoPackage.TradeDao.getTrade(TradeDao.java:26)

注意事项:

  1. 我还尝试在服务上使用@Transactional 而不是 道。结果相同。
  2. 类似的配置,但使用 Spring 3.0.5.RELEASEHibernate 3.6.5.Final 和扩展 HibernateDaoSupport 的 TradeDao 有效。

那么,有人有什么想法吗?
我今天一整天都在尝试很多事情。
我的头在旋转,我很生气,所以我一定错过了一些非常简单的东西,但现在我真的说不出来:)

【问题讨论】:

    标签: spring hibernate websphere jta spring-transactions


    【解决方案1】:

    我终于搞定了。

    正如我所料,我只是缺少一些小配置:)

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
            <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
        </props>
    </property>
    

    我之前在浏览时发现了这些配置选项,但由于某种原因,当我尝试它们时它们不起作用。可能当时我还有什么问题……(见Transaction strategy configuration章节)

    感谢大家的帮助!

    【讨论】:

      【解决方案2】:

      这可能很像这个人遇到的问题:http://forum.springsource.org/showthread.php?121109-Transaction-Propagations-and-Hibernate-4

      也就是说,如果在线程上找不到会话,HibernateDaoSupport(可能还有 HibernateTemplate)正在创建一个会话,而听起来新方法却没有。

      编辑:我刚刚意识到包含的链接正在使用 HibernateTransactionManager。我相信,如果您使用 JtaTransactionManager 而使用 HibernateTemplate,则必须手动在创建会话的目标周围应用建议。

      这也可能是他们在春天错过的东西:https://jira.springsource.org/browse/SPR-9404

      【讨论】:

      • 我不知道他的问题是否相关。我试图删除对HDaoSupportHTemplate 的所有依赖项(which is the recommended standard now,加上它们是somewhat deprecated,并且 org.springframework.orm.hibernate4 包不再具有它们)。我可以通过使用@Repository, @Transactional, SessionFactory.getCurrentSession() 来实现同样的目的。无论如何,我得到了它的工作,谢谢!
      【解决方案3】:

      默认情况下,@Transactional 注释适用于接口。由于您将使用无接口,因此您应该将 proxy-target-class="true" 属性添加到配置中的 标记中。

      【讨论】:

      • 感谢您的想法,但这不是问题所在。 proxy-target-class="true" 仅用于强制 spring 始终使用 CGLIB(即使在使用接口时)。默认情况下,Spring 足够聪明,如果目标对象至少有一个接口,它将创建动态代理,否则它将使用 CGLIB。见章节8.6 Proxying mechanisms
      猜你喜欢
      • 2012-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 2019-08-03
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      相关资源
      最近更新 更多