DBUnit在删除数据集时抛出NoSuchColumnException

时间:2014-09-18 12:22:27

标签: java junit dbunit

我正在使用DBUnit进行一些单元测试。我能够从xml文件中正确插入数据集,但是在完成每件事后我都无法清除数据集。

下面是ID列的表格架构(我在这里省略了其他列):

FIELD        TYPE              COLLATION          NULL    KEY     DEFAULT       Extra           PRIVILEGES                     
-----------  ----------------  -----------------  ------  ------  ------------  --------------  -------------------------------
ID           INT(11) UNSIGNED  (NULL)             NO      PRI     (NULL)        AUTO_INCREMENT  SELECT,INSERT,UPDATE,REFERENCES

下面是XML sataset:

<dataset>
    <MY_TABLE NAME="NISAY" />
</dataset>

我正在使用FlatXmlDataSetBuilder来构建数据集。在创建时,我使用InsertIdentityOperation.INSERT.execute(iConnection, dataSet);并删除我正在使用InsertIdentityOperation.DELETE.execute(iConnection, dataSet);

数据集已正确插入数据库,但在删除时会抛出以下异常:

org.dbunit.dataset.NoSuchColumnException: MY_TABLE.ID -  (Non-uppercase input column: ID) 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.dataset.AbstractTable.getColumnIndex(AbstractTable.java:78)
    at org.dbunit.dataset.DefaultTable.getValue(DefaultTable.java:197)
    at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:189)

为了测试每件事情是否合适,我从ID列中删除了unsigned约束并使用了以下数据集:

<dataset>
    <MY_TABLE ID="-99" NAME="NISAY" />
</dataset>

使用上述内容,一切正常。但是,ID必须为unsigned。如何在删除时告诉DBUnit忽略主键?我尝试使用过滤器,但不确定它们是否配置正确。

2 个答案:

答案 0 :(得分:0)

好的,问题是您无法在XML文件中提供ID,因为必须自动生成ID。并且DBUnit根据主键删除行。由于我没有提供主键(即ID),因此DBUnit无法删除数据集。

解决方案: 为数据集创建一个虚拟主键。 首先实施IColumnFilter

class MyPrimaryKeyFilter implements IColumnFilter {
        private String pseudoKey = null;

        MyPrimaryKeyFilter(String pseudoKey) {
            this.pseudoKey = pseudoKey;
        }

        public boolean accept(String tableName, Column column) {
            return column.getColumnName().equalsIgnoreCase(pseudoKey);
        }

}

然后将PROPERTY_PRIMARY_KEY_FILTER设置如下:

DatabaseConfig config = iConnection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_PRIMARY_KEY_FILTER, new MyPrimaryKeyFilter("SOME_OTHER_COLUMN_TO_BE_TREATED_AS_PK"));

现在,列SOME_OTHER_COLUMN_TO_BE_TREATED_AS_PK将被视为主键,您可以在数据集XML文件中为该列提供任何值。

答案 1 :(得分:0)

我在具有自定义数据类型的特定列上遇到了相同的错误(NoSuchColumnException)(使用了DatabaseConfig.PROPERTY_DATATYPE_FACTORY,新的OracleDataTypeFactory())。

用以下方法提取数据集:

IDatabaseTester databaseTester =new JdbcDatabaseTester("oracle.jdbc.driver.OracleDriver",
            address, "user", "password", "schema");
QueryDataSet queryDataSet = new QueryDataSet(databaseTester.getConnection());

String query = "SELECT * FROM CARS WHERE ID LIKE '123456'";
queryDataSet.addTable("FACTORY.CARS", query);

以上数据集旨在用于:

DatabaseOperation.DELETE.execute(connection, queryDataSet);

通过更改查询以仅返回识别要删除的行所需的列(避免使用自定义数据类型的行)并且异常停止来解决:

String query = "SELECT CAR_ID FROM CARS WHERE LICENSE_PLATE LIKE 'AB-FV-XY'";