Hibernate - 无法为当前线程获取事务同步会话

Hibernate - Could not obtain transaction-synchronized Session for current thread

我明白这个问题已经被问过很多次了,但大多数都不能解释我的问题:

@RequestMapping("/testing")
public String testing(HttpServletRequest request, final ModelMap model) 
{
    Transaction ut = session.openSession().beginTransaction();

    session.getCurrentSession(); // error here

    ut.commit();

    return "testing";
}

为什么我收到错误

Could not obtain transaction-synchronized Session for current thread.

如果我用 @Transactional 注释方法,它工作得很好。因为我的 spring 上下文中有 @EnableTransactionManagement

我想尝试一些东西来理解 getCurrentSessionopenSession 之间的区别,所以我在上面创建了测试用例。

getCurrentSession 是在活动事务上下文中调用的,为什么它仍然向我抛出错误???

参考this中的代码。

好的,经过这么长时间的研究,我发现我错过了下面的paragraph

You will not see these code snippets in a regular application; fatal (system) exceptions should always be caught at the "top". In other words, the code that executes Hibernate calls in the persistence layer, and the code that handles RuntimeException (and usually can only clean up and exit), are in different layers. The current context management by Hibernate can significantly simplify this design by accessing a SessionFactory. Exception handling is discussed later in this chapter.

所以那里显示的示例确实不会在常规情况下工作...

我必须做如下:

// BMT idiom with getCurrentSession()
try {
    UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");

    tx.begin();

    // Do some work on Session bound to transaction
    factory.getCurrentSession().load(...);
    factory.getCurrentSession().persist(...);

    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}

这意味着,getCurrentSession 的使用非常受限,在 active(和特定)交易中必须是 运行。