【问题标题】:DBUnit throwing NoSuchColumnException while deleting the datasetDBUnit 在删除数据集时抛出 NoSuchColumnException
【发布时间】:2014-09-18 12:22:26
【问题描述】:

我正在使用 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 数据集:

<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 在删除时忽略主键?我尝试使用过滤器,但不确定它们是否配置正确。

【问题讨论】:

    标签: java junit dbunit


    【解决方案1】:

    好的,所以问题是您不能在 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 文件中为该列提供任何值。

    【讨论】:

      【解决方案2】:

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

      正在提取数据集:

      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'";
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多