java - 在 Spring Transaction JUnit 测试中 Autowiring Hibernate session 的正确方法

标签 java hibernate spring transactions junit

这个问题类似于之前的 one .我正在尝试 @Autowire我的 Spring-JUnit-Transactional 测试之一中的 hibernate session ,但我得到了这个异常:

java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional ...

这是我的 JUnit 类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
public class MyTest {
    @Qualifier("session")
    @Autowired
    private Session session;

    @Test
    public void testSomething() {
        session.get(User.class, "me@here.com");
    }
}

如果我 @Autowire 一切正常一个 SessionFactory得到我的Session像这样以编程方式(而不是在 Spring XML 中定义它):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
public class MyTest{    
    @Qualifier("sessionFactory")
    @Autowired
    private SessionFactory sessionFactory;

    @Test
    public void testSomething() {
    Session session = SessionFactoryUtils.getSession(sessionFactory, false);
        session.get(User.class, "me@here.com");
    }
}

但是,如果我定义我的 Session,我可以让我的原始示例工作。在我的 Spring XML 中使用 <aop:scoped-proxy />像这样:

<?xml version="1.0" encoding="UTF-8"?>

<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        ">

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        ...
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation"><value>classpath:/hibernate.cfg.xml</value></property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
    </bean>

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

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

    <bean id="session" class="org.springframework.orm.hibernate3.SessionFactoryUtils" factory-method="getSession" scope="prototype">
        <constructor-arg ref="sessionFactory" />
        <constructor-arg value="false" />
        <!-- This is seems to be needed to get rid of the 'No Hibernate Session' error' -->
        <aop:scoped-proxy />
    </bean>
</beans>

我的问题是:为什么是 <aop:scoped-proxy />考虑到我的单元测试中应该只有一个线程绑定(bind)的事务上下文,需要吗?定义我的Hibernate Session 的正确方法是什么 bean ?

最佳答案

SessionFactoryUtils.getSession() 与任何其他获取 Session 的方式一样好。它和 HibernateDaoSupport.getSession() 做的事情是一样的。

您需要 scoped-proxy 的原因是时间问题。如果没有范围代理,它似乎是在测试开始之前注入(inject) session ,因此在事务开始之前注入(inject),所以你会得到错误。

通过添加作用域代理,它代理 Session 并注入(inject)它,因此它不会预先注入(inject)实际 session (在事务开始之前),而只会在测试运行时获取它并在它实际需要时调用它反对它。

关于java - 在 Spring Transaction JUnit 测试中 Autowiring Hibernate session 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1500775/

相关文章:

java - 如何通过选项卡导航activity的布局 android java

Hibernate saveorUpdate方法问题

java - 如何在 Hibernate 中重用模型而不创建新模型

java - 如何使用 Playframewok JPA 执行批量插入?

java - @RestController 抛出 HTTP 状态 406

spring - 是否可以使用 Spring AOP 或 Aspectj 为 Spring RestTemplate 类和任何外部 jar 类编写 AOP

java - 在没有 jasypt 的情况下解密 application.properties 中的密码

java - 在外部类对象上同步

java - 当我将样式表链接到 Thymeleaf 页面时,为什么 Spring Boot 会掉线?

java - 如何使用大括号在 Java 中定义多维数组?