【问题标题】:Reload database connection in Spring+Hibernate test case在 Spring+Hibernate 测试用例中重新加载数据库连接
【发布时间】:2012-02-22 21:44:20
【问题描述】:

我有一套使用 Spring 的 JUnit 运行器的系统测试,数据库配置如下所示:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.postgresql.Driver" />
    <property name="url" value="${clustercatalog.jdbc.url}" />
    <property name="username" value="${clustercatalog.jdbc.username}" />
    <property name="password" value="${clustercatalog.jdbc.password}" />
    <property name="initialSize" value="5" />
    <property name="maxActive" value="50" />
    <property name="poolPreparedStatements" value="true" />
    <property name="maxOpenPreparedStatements" value="100" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.xxx" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.show_sql">${jdbc.show.sql}</prop>
            <prop key="hibernate.id.new_generator_mappings">true</prop>
        </props>
    </property>
    <property name="namingStrategy" ref="namingStrategy" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />

测试用例有一个设置,我在其中运行一些 bash 脚本,这些脚本从先前完成的备份在基础 PostgreSQL 数据库上运行 pg_restore。这是因为我需要在每个测试方法之前数据库的相同状态是相同的。此恢复是在使用@BeforeTransaction 注释的方法中完成的。

测试类用注释

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "/systemTests-applicationContext.xml", "/applicationContext.xml" })
@TransactionConfiguration(defaultRollback = false)
@Transactional()

在测试中,当我执行使用当前休眠会话的代码时,它看不到已恢复的表。当我重新启动整个测试时,就会看到它们,但显然这是我想要的,但它证明数据库很好,但是当我执行 pg_restore 时 Spring/Hibernate 丢失了。我得到 SQLGrammarException 的表不存在。

我正在寻找一种手动重新启动与数据库的连接的方法。我怎样才能做到这一点?我应该以某种方式在 sessionFactory 或某些 Spring 组件上执行此操作吗?

【问题讨论】:

    标签: hibernate spring testing


    【解决方案1】:

    好的,我解决了这个问题。似乎 Spring 和 Hibernate 都没有意识到 DB 中发生的更改,如果 DBCP 池中有任何连接,它们会被重用,然后发生错误,因为连接下的模式已更改。所以我想在测试期间重置数据库时戳的地方是提供给 Hibernate SessionFactory 的 javax.sql.DataSource 对象。 DBCP BasicDataSource 没有此功能,因此我:

    1. 为 dataSource bean 创建了我自己的包装器。
    2. 将 bean 标记为原型作用域,这样每次我需要一个新的时我都不必自己构建它
    3. 为包装类添加了一个刷新方法,该方法为新的 bean 实例调用 applicationContext(自动装配到包装类)
    4. 将包装器 bean 注入 Hibernate 的 sessionFactory
    5. 自动将包装器连接到测试类,当我需要在测试中调用刷新方法时

    代码如下:

    @Component
    public class RefreshableDataSource implements DataSource {
    
      @Autowired
      DataSource dataSource;
      @Autowired
      ApplicationContext applicationContext;
    
      public void refresh() {
        dataSource = (DataSource) applicationContext.getBean("dataSource");
      }
    
      @Override
      public Connection getConnection() throws SQLException {
        return dataSource.getConnection();
      }
    
      ...other DataSource methods ...
    }
    

    applicationContext.xml:

    <bean id="dataSource" scope="prototype" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
                ......
    </bean>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="refreshableDataSource" />
        <property name="packagesToScan" value="com.xxx" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">${jdbc.show.sql}</prop>
                <prop key="hibernate.id.new_generator_mappings">true</prop>
            </props>
        </property>
        <property name="namingStrategy" ref="namingStrategy" />
    </bean>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      相关资源
      最近更新 更多