org.dbunit.dataset.NoSuchColumnException
Я получаю следующую ошибку при запуске моих тестов:
org.dbunit.dataset.NoSuchColumnException: myTable.MYFIELD - (Non-uppercase input column: myfield) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117)
Я установил точку останова в org.dbunit.dataset.AbstractTableMetaData#getColumnIndex
и обнаружил следующее. В IntelliJ Idea метод выглядит так:
public int getColumnIndex(String columnName) throws DataSetException
{
logger.debug("getColumnIndex(columnName={}) - start", columnName);
if(this._columnsToIndexes == null)
{
// lazily create the map
this._columnsToIndexes = createColumnIndexesMap(this.getColumns());
}
String columnNameUpperCase = columnName.toUpperCase();
Integer colIndex = (Integer) this._columnsToIndexes.get(columnNameUpperCase);
if(colIndex != null)
{
return colIndex.intValue();
}
else
{
throw new NoSuchColumnException(this.getTableName(), columnNameUpperCase,
" (Non-uppercase input column: "+columnName+") in ColumnNameToIndexes cache map. " +
"Note that the map's column names are NOT case sensitive.");
}
}
Значение this.getColumns()
не содержит никаких Column
с Column.columnName
соответствие параметра columnName
, Следовательно colIndex
становится null
и исключение брошено.
Похоже, DBUnit ищет индекс столбца в неверных метаданных таблицы.
Как я могу это исправить?
Примечание: я унаследовал этот код от кого-то другого (не писал его).
2 ответа
Я чувствую тот факт, что вы не можете поделиться кодом. Это делает вещи немного сложными, но вот ответ, который я считаю разумным, учитывая ограничения:
Я смог легко воспроизвести это исключение, используя минимальный проект Spring Boot/DbUnit, клонированный из GitHub. Возможно, мои наблюдения составят подсказку, которую вы ищете, или, по крайней мере, вдохновят на лучший ответ.
меры
- Клонировать проект и установить зависимости.
- Запустить
HsqldbexampleApplicationTests.contextLoads()
тестовое задание. Это проходит. - Попасть в
StaticResource.java
и изменить один из@Column
аннотаций.
Например, я изменил:
@Column(name = "CONTENT")
private String content;
чтобы:
@Column(name = "CONTENTZ")
private String content;
- Запустите тест снова и соблюдайте исключение
- Кроме того, вы можете попасть в
sampleData.xml
и изменитьCONTENT
Атрибуты там (имя атрибута), чтобы произвести то же исключение.
наблюдения
- Тест получает данные от
/META-INF/dbtest/sampleData.xml
, Обратите вниманиеCONTENT
приписывать. - Ресурс имеет
@Column
аннотация которогоname
должен соответствовать атрибуту, найденному вsampleData.xml
элементы. - Поскольку ваша проблема также связана с запуском тестов, возможно, ваш код и
.xml
(?), который увлажняет ваше тестовое хранилище данных, просто не синхронизировано по отношению к имени столбца.
Дальнейшее значение файла XML?
Мои попытки спровоцировать это исключение путем изменения запросов и имен переменных экземпляра не увенчались успехом. Все, что я пробовал, заставляло компилятор жаловаться, поэтому я исключил это.
Например, я также проверил этот репозиторий и попытался изменить запрос и переменную экземпляра, но компилятор мешал на каждом этапе. Изменение запроса:
Изменение имени переменной экземпляра:
Где искать
- В любом месте в любом коде Java, где у вас есть
@Column
сMYFIELD
внутри него. Помните, аннотации могут занимать несколько строк в файле. - Любые XML-файлы, содержащие
MYFIELD
, - Предполагая, что тестируемый код работает нормально, а ваши проблемы ограничиваются запуском тестов, механизм, который вводит данные в ваш тест, является основным подозреваемым. Если это не XML-файл, что это?
Не понятно из вашего поста, как вы получаете _columnsToIndexes
Это похоже на часть кода отражения, который зависит от вашего POJO. В этом случае проблема может быть в Lazy
инициализация объекта. Ленивые инициализированные объекты - это не просто объект-сущность, а своего рода прокси-сервер, и попытка получить его свойства через отражение может вызвать эту проблему. Вероятно, вы должны попытаться добавить какой-то метод прокси в вас createColumnIndexesMap
, Вот пример:
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new InternalServerException("Entity passed for initialization is null");
}
T unproxy = entity;
Hibernate.initialize(entity);
if (isProxy(entity)) {
unproxy = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return unproxy;
}
public static <T> boolean isProxy(T entity) {
return entity instanceof HibernateProxy;
}
конечно это зависит от вашего ORM, вот пример для Hibernate