通过dbunit使用设置数据重新创建h2 db

时间:2012-01-05 05:34:35

标签: spring h2 dbunit

某些背景信息:

我正在使用spring批处理POC来替换数据提取和报告框架。我们从Oracle数据库中读取数据并从那里生成CSV报告。现在我有这个工作和单元测试连接到oracle db。但是,我更愿意删除Oracle db的外部依赖关系来测试。

问题:

当需要向db添加数据时,dbunit抱怨表'Account'不存在。

日志记录:

我可以看到要删除的sql并创建被触发的表:

06:54:58,940 DEBUG org.springframework.jdbc.core.JdbcTemplate:417 - Executing SQL statement [DROP TABLE ACCOUNT CASCADE CONSTRAINTS]
06:54:58,988 DEBUG org.springframework.jdbc.core.JdbcTemplate:417 - Executing SQL statement [CREATE TABLE ACCOUNT ( ID NUMBER(22) NOT NULL, CURRENT_BALANCE NUMBER(22) NOT NULL, RESERVED_AMOUNT NUMBER(22), ACCOUNT_TYPE VARCHAR2(50) NOT NULL, CURRENCY_CODE CHAR(3) NOT NULL, ACCOUNT_STATUS VARCHAR2(50) NOT NULL, PRODUCT_ID NUMBER(22) DEFAULT 0, CLIENT_CODE VARCHAR2(50) NOT NULL, LEDGER_ACCOUNT_TYPE VARCHAR2(50), CHANGED_BY VARCHAR2(50) NOT NULL, CHANGED_ON TIMESTAMP(6) NOT NULL, VERSION INTEGER DEFAULT 0, ACTIVATION_DATE TIMESTAMP(6), NEXT_BILLING_DATE TIMESTAMP(6), MSISDN VARCHAR2(50), IS_DEFAULT CHAR(1) DEFAULT '0', CONSTRAINT PK_ACCOUNT PRIMARY KEY (ID) )]

我有一个SQL脚本来为dbunit创建db模式和flat xml数据以进行填充。从日志记录中我可以看到以下情况:

Dbunit加载xml数据:

06:54:59,886 DEBUG org.dbunit.dataset.xml.FlatXmlProducer:414 - startElement(uri=, localName=, qName=ACCOUNT, attributes=com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@1e2b807) - start
06:54:59,886 DEBUG org.dbunit.dataset.OrderedTableNameMap:149 - getLastTableName() - start
06:54:59,886 DEBUG org.dbunit.dataset.OrderedTableNameMap:127 - isLastTable(tableName=ACCOUNT) - start
06:54:59,886 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 - getTableName(tableName=ACCOUNT) - start
06:54:59,886 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT
06:54:59,887 DEBUG org.dbunit.dataset.xml.FlatXmlProducer:184 - createTableMetaData(tableName=ACCOUNT, attributes=com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$AttributesProxy@1e2b807) - start
06:54:59,912 DEBUG org.dbunit.dataset.Columns:71 - getColumns(columnNames=[], columns=[(ID, UNKNOWN, nullableUnknown), (CURRENT_BALANCE, UNKNOWN, nullableUnknown), (RESERVED_AMOUNT, UNKNOWN, nullableUnknown), (ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CURRENCY_CODE, UNKNOWN, nullableUnknown), (ACCOUNT_STATUS, UNKNOWN, nullableUnknown), (PRODUCT_ID, UNKNOWN, nullableUnknown), (CLIENT_CODE, UNKNOWN, nullableUnknown), (LEDGER_ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CHANGED_BY, UNKNOWN, nullableUnknown), (CHANGED_ON, UNKNOWN, nullableUnknown), (VERSION, UNKNOWN, nullableUnknown), (IS_DEFAULT, UNKNOWN, nullableUnknown)]) - start
06:54:59,912 DEBUG org.dbunit.dataset.OrderedTableNameMap:191 - add(tableName=ACCOUNT, object=tableName=ACCOUNT, columns=[(ID, UNKNOWN, nullableUnknown), (CURRENT_BALANCE, UNKNOWN, nullableUnknown), (RESERVED_AMOUNT, UNKNOWN, nullableUnknown), (ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CURRENCY_CODE, UNKNOWN, nullableUnknown), (ACCOUNT_STATUS, UNKNOWN, nullableUnknown), (PRODUCT_ID, UNKNOWN, nullableUnknown), (CLIENT_CODE, UNKNOWN, nullableUnknown), (LEDGER_ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CHANGED_BY, UNKNOWN, nullableUnknown), (CHANGED_ON, UNKNOWN, nullableUnknown), (VERSION, UNKNOWN, nullableUnknown), (IS_DEFAULT, UNKNOWN, nullableUnknown)], keys=[]) - start
06:54:59,913 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 -getTableName(tableName=ACCOUNT) - start
06:54:59,913 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT
06:54:59,913 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 - getTableName(tableName=ACCOUNT) - start
06:54:59,913 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT
06:54:59,913 DEBUG org.dbunit.dataset.CachedDataSet:135 - startTable(metaData=tableName=ACCOUNT, columns=[(ID, UNKNOWN, nullableUnknown), (CURRENT_BALANCE, UNKNOWN, nullableUnknown), (RESERVED_AMOUNT, UNKNOWN, nullableUnknown), (ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CURRENCY_CODE, UNKNOWN, nullableUnknown), (ACCOUNT_STATUS, UNKNOWN, nullableUnknown), (PRODUCT_ID, UNKNOWN, nullableUnknown), (CLIENT_CODE, UNKNOWN, nullableUnknown), (LEDGER_ACCOUNT_TYPE, UNKNOWN, nullableUnknown), (CHANGED_BY, UNKNOWN, nullableUnknown), (CHANGED_ON, UNKNOWN, nullableUnknown), (VERSION, UNKNOWN, nullableUnknown), (IS_DEFAULT, UNKNOWN, nullableUnknown)], keys=[]) - start
06:54:59,916 DEBUG org.dbunit.dataset.OrderedTableNameMap:149 - getLastTableName() - start
06:54:59,916 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 - getTableName(tableName=ACCOUNT) - start
06:54:59,916 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT
06:54:59,916 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=ID) - start
06:54:59,917 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=CURRENT_BALANCE) - start
06:54:59,917 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=RESERVED_AMOUNT) - start
06:54:59,933 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=ACCOUNT_TYPE) - start
06:54:59,933 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=CURRENCY_CODE) - start
06:54:59,933 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=ACCOUNT_STATUS) - start
06:54:59,934 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=PRODUCT_ID) - start
06:54:59,934 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=CLIENT_CODE) - start
06:54:59,934 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=LEDGER_ACCOUNT_TYPE) - start
06:54:59,934 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=CHANGED_BY) - start
06:54:59,934 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=CHANGED_ON) - start
06:54:59,935 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=VERSION) - start
06:54:59,935 DEBUG org.dbunit.dataset.AbstractTableMetaData:101 - getColumnIndex(columnName=IS_DEFAULT) - start
06:54:59,935 DEBUG org.dbunit.dataset.OrderedTableNameMap:149 - getLastTableName() - start
06:54:59,935 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 - getTableName(tableName=ACCOUNT) - start
06:54:59,935 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT

最后:

06:55:00,037 DEBUG org.dbunit.database.DatabaseDataSet:279 - getTableMetaData(tableName=ACCOUNT) - start
06:55:00,037 DEBUG org.dbunit.database.DatabaseDataSet:173 - initialize() - start
06:55:00,037 DEBUG org.dbunit.database.DatabaseDataSet:182 - Initializing the data set from the database...
06:55:00,037 DEBUG org.dbunit.database.DatabaseDataSourceConnection:113 - getConnection() - start
06:55:00,090 DEBUG org.dbunit.database.DatabaseDataSet:203 - 
    database product name=H2
    database version=1.3.163 (2011-12-30)
    database major version=1
    database minor version=3
    jdbc driver name=H2 JDBC Driver
    jdbc driver version=1.3.163 (2011-12-30)
    jdbc driver major version=1
    jdbc driver minor version=3
06:55:00,090 DEBUG org.dbunit.database.DatabaseDataSet:204 - metadata resultset=org.apache.commons.dbcp.DelegatingResultSet@be071a
06:55:00,090 DEBUG org.dbunit.dataset.OrderedTableNameMap:253 - getTableName(tableName=ACCOUNT) - start
06:55:00,090 DEBUG org.dbunit.dataset.OrderedTableNameMap:264 - getTableName(tableName=ACCOUNT) - end - result=ACCOUNT
06:55:00,090 ERROR org.dbunit.database.DatabaseDataSet:286 - Table 'ACCOUNT' not found in tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[], _tableMap={}, _caseSensitiveTableNames=false]

代码

AbstractReportTest.java用于删除/创建数据库模式,然后通过dbunit加载数据。

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseDataSourceConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Assert;
import org.junit.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;

@Transactional
public abstract class AbstractReportTest {
    private static final Logger LOG = LoggerFactory.getLogger(AbstractReportTest.class);

    protected static final String NEW_LINE = System.getProperty("line.separator");
    private static final String DROP_SQL = "DROP";

    @Autowired
    private DataSource datasource;

    @Autowired
    @Qualifier(value="testData")
    private Resource testData;

    @Autowired
    @Qualifier(value="createScript")
    private Resource createScript;

    @Autowired
    private JdbcTemplate template;

    protected abstract String getSchema();

    @Before
    public void init() {
        IDatabaseConnection dbUnitCon = null;
        try {
            recreateDb();

            dbUnitCon = new DatabaseDataSourceConnection(datasource, getSchema());
            dbUnitCon.getConfig().setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);

            FlatXmlDataSetBuilder dataBuilder = new FlatXmlDataSetBuilder();
            FlatXmlDataSet dataset = dataBuilder.build(testData.getFile());

            DatabaseOperation.INSERT.execute(dbUnitCon, dataset);
        } catch(IOException ioException) {
            LOG.error("", ioException);

            Assert.fail();
        } catch(DataSetException dse) {
            LOG.error("", dse);

            Assert.fail();
        } catch (DatabaseUnitException due) {
            LOG.error("", due);

            Assert.fail();
        } catch (SQLException sqlException) {
            LOG.error("", sqlException);

            Assert.fail();
        }
    }

    private void recreateDb() throws IOException {
        File sqlFile = createScript.getFile();
        LOG.info("Loading sql file: {}", sqlFile.getName());
        String sql = new String(FileCopyUtils.copyToByteArray(sqlFile));

        String[] queries = sql.split(";" + NEW_LINE);

        LOG.info("Preparing to run {} queries.", queries.length);
        for(String currentQuery : queries) {
            try {
                template.execute(currentQuery);
            } catch (DataAccessException dae) {
                if(currentQuery.indexOf(DROP_SQL) == -1) {
                    Assert.fail("Failed creating db tables.");
                }
            }
        }

        LOG.info("Completed db setup.");
    }
}

Spring配置:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <util:properties id="jdbcProps" location="classpath:/jdbc.properties" />

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>

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

    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="username" value="#{jdbcProps['brandgroup.jdbc.username']}"/>
        <property name="password" value="#{jdbcProps['brandgroup.jdbc.password']}"/>
        <property name="url" value="#{jdbcProps['brandgroup.jdbc.url']}"/>
        <property name="driverClassName" value="#{jdbcProps['brandgroup.jdbc.driver']}"/>
    </bean>

    <bean id="testTxnManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>

    <bean id="testTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
         <property name="dataSource" ref="datasource"/>
    </bean>

</beans>

drop / create代码使用与db unit部分相同的数据源,因此我认为它不会在mem h2实例中创建一个新的。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我也遇到过这个。当dbunit尝试删除表时,它找不到它,因此也就是问题。我通过在删除DDL中添加“IF EXISTS”来修复它。

希望有所帮助。