如何使用Dbunit FlatXmlDataSet填充Oracle TIMESTAMP WITH ZONE字段

时间:2016-05-31 12:02:34

标签: oracle dbunit timestamp-with-timezone spring-test-dbunit

我正在尝试通过填充具有AsynchronousSocketChannel类型列的表来为数据库单元测试设置数据,如下所示:

TIMESTAMP(6) WITH TIME ZONE

但是当我运行测试时,我不断收到以下异常:

<timetable START_TIME="2015-03-01 10.00.00.000000000" END_TIME="2015-03-02 10.00.00.000000000"/>

我为时间戳字段尝试了不同的格式,包括添加时区后缀+ XX:XX org.dbunit.dataset.NoSuchColumnException: TIMETABLE.START_TIME - (Non-uppercase input column: START_TIME) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive. at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117) at org.dbunit.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:89) at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:143) at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79) at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:194) at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:66) at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:185) at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249) 无济于事。 我也尝试使用VM参数2015-03-01 10.00.00.000000000 +00.00运行测试,但这也没有帮助。

有谁知道如何实现这一目标?

编辑1

我在控制台中注意到以下警告:

-Duser.timezone=UTC

所以看起来Dbunit不支持2016-05-31 14:54:23 WARN SQLHelper:429 - TIMETABLE.START_TIME data type (-101, 'TIMESTAMP(6) WITH TIME ZONE') not recognized and will be ignored. See FAQ for more information. 2016-05-31 14:54:23 WARN SQLHelper:429 - TIMETABLE.END_TIME data type (-101, 'TIMESTAMP(6) WITH TIME ZONE') not recognized and will be ignored. See FAQ for more information. 数据类型并忽略它,因此TIMESTAMP WITH TIME ZONE异常

编辑2

实际上dbunit已经通过NoSuchColumnException类支持TIMESTAMP数据类型。然后配置如下:

OracleDataTypeFactory

不幸的是,在这些配置更改之后,数据类型问题仍然存在,因为dbunit DatabaseConfig.datatypeFactory属性被DbUnitTestExecutionListener重新设置为默认的<bean id="oracleDataTypeFactory" class="org.dbunit.ext.oracle.OracleDataTypeFactory"/> <bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean"> <property name="datatypeFactory" ref="oracleDataTypeFactory" /> </bean> ,它不支持TIMESTAMP数据类型

1 个答案:

答案 0 :(得分:0)

我设法通过删除Spring-dbunit特定注释(TIMESTAMP@TestExecutionListeners)来加载@DbUnitConfiguration数据。我仍然必须使用@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)。然后我使用了旧的&#39; Dbunit设置和拆除数据以及检查数据期望的方法。这不像Spring-dbunit注释@DatabaseSetup@DatabaseTearDown@ExpectedDatabase那样简洁,但确实有效(请参阅下面的代码片段)。我还在我的测试上下文中保留了OracleDataTypeFactory;这对于Dbunit可以识别的TIMESTAMP数据类型至关重要。

我认为我遇到的问题可能是spring-dbunit测试执行监听器中的错误表现。我特别怀疑DbUnitTestExecutionListener

<强>设定:

@Before
    public void setUp() throws SQLException, IOException, DataSetException, DatabaseUnitException {    
        Resource resource = new ClassPathResource("path/to/data_setup.xml");
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        builder.setColumnSensing(true);
        FlatXmlDataSet dataSetup = builder.build(resource.getInputStream());
        DatabaseOperation.CLEAN_INSERT.execute(dbUnitDatabaseConnection, dataSetup);    
    }

<强>拆解:

@After
    public void tearDown() throws SQLException, IOException, DataSetException, DatabaseUnitException {
        Resource resource = new ClassPathResource("path/to/data_teardown.xml");
        FlatXmlDataSet dataTearDown = new FlatXmlDataSetBuilder().build(resource.getInputStream());
        DatabaseOperation.DELETE_ALL.execute(dbUnitDatabaseConnection, dataTearDown);
    }

期望(在测试方法中):

QueryDataSet actualDataSet = new QueryDataSet(dbUnitDatabaseConnection);
actualDataSet.addTable("YOUR_TABLE", "<YOUR_SQL_QUERY>");
FlatXmlDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(new ClassPathResource("path/to/data_expectation.xml").getInputStream());
Assertion.assertEquals(expectedDataSet, actualDataSet);