Spring / Hibernate / JUnit - 没有 Hibernate 会话绑定到线程

发布于 2024-07-16 23:48:53 字数 3101 浏览 4 评论 0原文

我试图在测试用例中访问当前的休眠会话,并收到以下错误:

org.hibernate.HibernateException:否 Hibernate Session 绑定到线程,并且 配置不允许创建 非交易性的一个在这里 org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63) 在 org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574)

我显然错过了某种设置,但不确定是什么。

任何帮助将不胜感激。 这是我第一次接触 Hibernate / Spring 等,学习曲线肯定很陡峭!

代码如下:

有问题的类:

public class DbUnitUtil extends BaseDALTest {
    @Test
    public void exportDtd() throws Exception
    {

        Session session = sessionFactory.getCurrentSession();

        session.beginTransaction();
        Connection hsqldbConnection = session.connection(); 

        IDatabaseConnection connection = new DatabaseConnection(hsqldbConnection);

        // write DTD file
        FlatDtdDataSet.write(connection.createDataSet(), new FileOutputStream("test.dtd"));
    }
}

基类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class BaseDALTest extends AbstractJUnit4SpringContextTests {
    public BaseDALTest()
    {
        super();
    }
        @Resource
        protected SessionFactory sessionFactory;
}

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>org.hsqldb.jdbcDriver</value>
        </property>
        <property name="url">
            <value>jdbc:hsqldb:mem:sample</value>
        </property>
        <property name="username">
            <value>sa</value>
        </property>
        <property name="password">
            <value></value>
        </property>
    </bean>

    <bean id="sessionFactory" class="com.foo.spring.AutoAnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="entityPackages">
            <list>
                <value>com.sample.model</value>
            </list>
        </property>
        <property name="schemaUpdate">
            <value>true</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
</beans>

I'm trying to access the current hibernate session in a test case, and getting the following error:

org.hibernate.HibernateException: No
Hibernate Session bound to thread, and
configuration does not allow creation
of non-transactional one here at
org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
at
org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574)

I've clearly missed some sort of setup, but not sure what.

Any help would be greatly appreciated. This is my first crack at Hibernate / Spring etc, and the learning curve is certainly steep!

Code follows:

The offending class:

public class DbUnitUtil extends BaseDALTest {
    @Test
    public void exportDtd() throws Exception
    {

        Session session = sessionFactory.getCurrentSession();

        session.beginTransaction();
        Connection hsqldbConnection = session.connection(); 

        IDatabaseConnection connection = new DatabaseConnection(hsqldbConnection);

        // write DTD file
        FlatDtdDataSet.write(connection.createDataSet(), new FileOutputStream("test.dtd"));
    }
}

Base class:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class BaseDALTest extends AbstractJUnit4SpringContextTests {
    public BaseDALTest()
    {
        super();
    }
        @Resource
        protected SessionFactory sessionFactory;
}

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>org.hsqldb.jdbcDriver</value>
        </property>
        <property name="url">
            <value>jdbc:hsqldb:mem:sample</value>
        </property>
        <property name="username">
            <value>sa</value>
        </property>
        <property name="password">
            <value></value>
        </property>
    </bean>

    <bean id="sessionFactory" class="com.foo.spring.AutoAnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="entityPackages">
            <list>
                <value>com.sample.model</value>
            </list>
        </property>
        <property name="schemaUpdate">
            <value>true</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
</beans>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

℉服软 2024-07-23 23:48:54

编写代码来进行测试应该足够了

Session session = sessionFactory.getCurrentSession();

通过上述 Spring 配置,在方法和类中 。 会话管理由 Hibernate / Spring /JUnit 测试配置完成,稍后在真实应用程序中的 Hibernate / Spring 配置中完成。

这就是我的测试的工作原理。 在最终的 Web 应用程序中,将自动有一个与当前 Web 请求关联的 Hibernate 会话,因此在测试中不应有 sessionFactory.openSession() 调用。

With the above Spring configuration, it should be sufficient to code

Session session = sessionFactory.getCurrentSession();

in your method and class to test. Session management is done by the Hibernate / Spring /JUnit test configuration, as later is done in the Hibernate / Spring configuration in the real application.

This is how it worked for my tests. In the final web application there will automatically be a Hibernate session associated with the current web request and therefore in testing there should be no sessionFactory.openSession() call.

绾颜 2024-07-23 23:48:54

呃。

会话会话 =
sessionFactory.openSession();

Session session = sessionFactory.getCurrentSession();

糟糕。

(因为这是错误的,所以进行了编辑,并得到了支持)。

Duh.

Session session =
sessionFactory.openSession();

Session session = sessionFactory.getCurrentSession();

Oops.

(Edited since this was wrong, and getting upvoted).

记忆消瘦 2024-07-23 23:48:54

Spring 会忽略 hibernate.current_session_context_class=thread 属性(您不使用该属性),并将 Hibernate 的 SessionFactory 包装在它自己的事务版本中,如下所述此处

设置属性

<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>

解决方案是在会话工厂 bean 配置中

Spring ignores hibernate.current_session_context_class=thread property (which you don't use) and wraps Hibernate’s SessionFactory in it's own transactional version as explained here

The solution to this is to set the property

<property name="exposeTransactionAwareSessionFactory"><value>false</value></property>

in session factory bean configuration

三生一梦 2024-07-23 23:48:53

错误的,这只会用会话管理代码填充您的代码。

首先,在您的上下文中添加一个事务管理 bean:

    <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

第二件事,扩展 AbstractTransactionalJUnit4SpringContextTests

    public class BaseDALTest 
           extends AbstractTransactionalJUnit4SpringContextTests{

第三件事,用注释您的测试类

    @TransactionConfiguration
    @Transactional

如果您的事务划分是正确的(围绕您的 dao 或服务),您应该完成。

在代码周围(甚至在测试内部)散布会话和事务处理代码并不好。

Wrong, that will just fill your code with session management code.

First, add a transaction management bean in your context:

    <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

The second thing, extend AbstractTransactionalJUnit4SpringContextTests

    public class BaseDALTest 
           extends AbstractTransactionalJUnit4SpringContextTests{

Third thing, annotate you test class with

    @TransactionConfiguration
    @Transactional

If your transaction demarcation is correct(surrounding your dao or service) you should be done.

It's not nice to sprinkle session and transaction handling code all around your code (even inside your tests).

亢潮 2024-07-23 23:48:53

请参阅 Spring 文档。 有整整一章是关于测试的,还有一节是关于事务管理的:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/testing.html#testing-tx

我已经已成功扩展 AbstractTransactionalJUnit4SpringContextTests,但有一个解决方法:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        // DAO has access to the session through sessionFactory.getCurrentSession()
        myDao.findSomething(id);
    }
});

Please refer to the Spring documentation. There is a whole chapter on testing, and a section on transaction management:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/testing.html#testing-tx

I've had success extending AbstractTransactionalJUnit4SpringContextTests, but there's a workaround:

TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    @Override
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        // DAO has access to the session through sessionFactory.getCurrentSession()
        myDao.findSomething(id);
    }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文