【问题标题】:DbUnit H2 in memory db with Spring and Hibernate带有 Spring 和 Hibernate 的内存数据库中的 DbUnit H2
【发布时间】:2013-08-11 18:42:39
【问题描述】:

您好,我正在尝试使用 JPA 和单元测试进行一点 POC,以验证数据库模式是否已创建。我正在使用 H2 DB 并设置为 Hibernate 从实体创建模式,但是当 DbUnit 尝试从数据集中初始化 DB 时,我总是得到一个表......在 tableMap 中找不到。我读到我必须将属性 DB_CLOSE_DELAY=-1 添加到 DB URL,但是就像在 Hibernate 创建架构后,当 DbUnit 尝试初始化时 DB 丢失了。

有什么想法吗?非常感谢任何帮助。

这是我的配置:

application-context.xml

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSourceH2" />
    <property name="packagesToScan" value="com.xxx.model" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="true" />
            <property name="showSql" value="true" />
            <!-- property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect" /-->
            <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
            <!-- property name="database" value="MYSQL" /-->
        </bean>    
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="javax.persistence.validation.mode">CALLBACK</prop>
            </props>
        </property>
    </bean>

<bean id="dataSourceH2"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.h2.Driver" />
        <property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

RepositoryTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/application-context-test.xml" })
@Transactional
public class SystemEntityRepositoryH2Test {

    @Inject
    private SystemEntityRepository repository;

    @Inject
    private DataSource dataSourceH2;

    private IDatabaseConnection connection;

    @Before
    public void setUp() throws Exception {
        IDatabaseConnection dbUnitCon = null;
        dbUnitCon = new DatabaseDataSourceConnection(dataSourceH2, "testdb");
        dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);

        IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
        DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);

    }

    @After
    public void tearDown() throws Exception {
        //DatabaseOperation.DELETE_ALL.execute(this.getConnection(), this.getDataSet(dataSetFile));
    }

    @Test
    public void test() throws Exception {

    }

    protected IDataSet getDataSet(String dataSetFile) throws Exception {
        ResourceLoader resourceLoader = new ClassRelativeResourceLoader(this.getClass());
        Resource resource = resourceLoader.getResource(dataSetFile);

        if (resource.exists()) {
            return new FlatXmlDataSetBuilder().build(resource.getInputStream());
        }

        return null;
    }
}

dataset-systementity.xml

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <System_Entities id="2" name="NAME" phone01="+52-55-55555555" email="a@a.com"
                    address01="Street" address02="123" address03="1" address04="Address04"
                    address05="Address05" city="City" state="State" country="MX"
                    zipcode="12345" />
</dataset>

错误

ERROR DatabaseDataSet:286 - Table 'System_Entities' not found in tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[], _tableMap={}, _caseSensitiveTableNames=false]

我可以看到表是hibernate创建的,因为日志显示所有的sql语句都没有错误。

谢谢。

解决方案

感谢马克罗宾逊 我将 setUp 方法修改为:

@Before
    public void setUp() throws Exception {
        IDatabaseConnection dbUnitCon = null;
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        Session session = entityManager.unwrap(Session.class);
        SessionImplementor si = (SessionImplementor) session;
        Connection conn = si.getJdbcConnectionAccess().obtainConnection();
        dbUnitCon = new DatabaseConnection(conn);

        //dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);

        IDataSet dataSet = this.getDataSet("dataset-systementity.xml");
        DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
    }

现在可以了,我不明白的是如果我使用 HSQLDB 我没有这个问题。

【问题讨论】:

    标签: spring hibernate unit-testing h2 dbunit


    【解决方案1】:

    问题是 DBUnit 在 Hibernate 初始化之前加载了表数据。

    作为@setup 的一部分,您需要获取Hibernate 会话。这应该会导致 Hibernate 创建您的表。你甚至可以通过执行一个简单的查询来强制它,比如select 1

    【讨论】:

    • 谢谢!现在的问题出在我的测试方法中,我使用存储库对象保存了一个对象,之后我想使用 dbUnitCon 中的 createDataSet() 获取实际的数据集,但我得到一个“尝试锁定表的超时......”错误,我将 MVCC=TRUE 添加到连接 url 并且它可以工作,但数据集仅包含 dbunit 初始化的数据,它不包含与存储库对象一起保存的对象。
    • 继续我之前的评论,就像存储库使用的事务尚未提交,当我尝试获取实际数据集时,我看不到该更改,我不知道该去哪里在此之后。
    猜你喜欢
    • 1970-01-01
    • 2017-02-20
    • 2010-12-29
    • 2013-05-01
    • 2015-03-03
    • 2013-02-03
    • 2019-02-22
    • 2020-02-02
    • 1970-01-01
    相关资源
    最近更新 更多