DBUnit выбрасывает NoSuchColumnException при удалении набора данных
Я делаю некоторые модульное тестирование с использованием DBUnit. Я могу правильно вставить набор данных из файла xml, но не могу очистить набор данных после того, как все будет завершено.
Ниже приведена моя схема таблицы для столбца идентификатора (другие столбцы здесь опущены):
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)
Просто чтобы проверить, что все в порядке, я удалил unsigned
ограничение из столбца ID и использовал следующий набор данных:
<dataset>
<MY_TABLE ID="-99" NAME="NISAY" />
</dataset>
Используя вышеизложенное, все работало нормально. Однако идентификатор должен быть unsigned
, Как мне сказать DBUnit игнорировать первичный ключ при удалении? Я пытался использовать фильтры, но не уверен, что они были настроены правильно.
2 ответа
Итак, проблема в том, что вы не можете дать идентификатор в файле XML, потому что идентификатор должен быть сгенерирован автоматически. И DBUnit удаляет строки на основе первичного ключа. Поскольку я не предоставлял первичный ключ (т. Е. Идентификатор), 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-файле набора данных.
У меня была та же ошибка (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'";