DbUnit: NoSuchColumnException и чувствительность к регистру

перед публикацией этого я немного погуглил, я искал в dbunit-user архивы и немного также в списке ошибок DbUnit, но я не нашел, что находясь в поиске. К сожалению, ответы здесь не помогло.

Я использую DbUnit 2.4.8 с MySQL 5.1.x для заполнения в настройке некоторых таблиц JForum. Проблема впервые появляется в таблице jforum_users, созданной этим скриптом

CREATE TABLE `jforum_users` (
       `user_id` INT(11) NOT NULL AUTO_INCREMENT,
       `user_active` TINYINT(1) NULL DEFAULT NULL,
       `username` VARCHAR(50) NOT NULL DEFAULT '',
       `user_password` VARCHAR(32) NOT NULL DEFAULT '',
       [...]
       PRIMARY KEY (`user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=14

выполнение обновления как операции установки базы данных следующее исключение поднятый.

org.dbunit.dataset.NoSuchColumnException: jforum_users.USER_ID -
(Non-uppercase input column: USER_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.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:89)
       at org.dbunit.operation.RefreshOperation.execute(RefreshOperation.java:98)
       at org.dbunit.AbstractDatabaseTester.executeOperation(AbstractDatabaseTester.java:190)
       at org.dbunit.AbstractDatabaseTester.onSetup(AbstractDatabaseTester.java:103)
       at net.jforum.dao.generic.AbstractDaoTest.setUpDatabase(AbstractDaoTest.java:43)

Я заглянул в AbstractTableMetaData.java источники и ничего не кажется-статически-неправильным. Метод

private Map createColumnIndexesMap(Column[] columns)

использует

columns[i].getColumnName().toUpperCase()

при написании ключей карты. А потом метод

public int getColumnIndex(String columnName)

использует

String columnNameUpperCase = columnName.toUpperCase();
Integer colIndex = (Integer) this._columnsToIndexes.get(columnNameUpperCase);

для чтения объекта с карты.

Я действительно не могу понять, что происходит... Кто-нибудь может мне помочь?

редактировать после последнего ответа @ limc

Я использую PropertiesBasedJdbcDatabaseTester для настройки моего DbUnit env, как показано ниже:

Properties dbProperties = new Properties();
dbProperties.load(new FileInputStream(testConfDir+"/db.properties"));
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, 
    dbProperties.getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS));
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, 
    dbProperties.getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL));
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, 
    dbProperties.getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME));
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, 
    dbProperties.getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD));
System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA, 
    dbProperties.getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA));

databaseTester = new PropertiesBasedJdbcDatabaseTester();
databaseTester.setSetUpOperation(getSetUpOperation());
databaseTester.setTearDownOperation(getTearDownOperation());

IDataSet dataSet = getDataSet();
databaseTester.setDataSet(dataSet);

databaseTester.onSetup();

9 ответов


у меня есть основания полагать, что проблема возникла из


у меня была аналогичная проблема сегодня (используя интерфейс IDatabaseTester, добавленный в v2.2 против MySQL) и потратил несколько часов, разрывая мои волосы над ним. OP использует PropertiesBasedJdbcDatabaseTester, в то время как я использовал его "Родительский" JdbcDatabaseTester.

д. Банкрофт был FAQ ответ, связанный с этим NoSuchColumnException (специфично для MySQL), но для меня это похоже на недосмотр, что он пренебрегает упоминанием о том, что каждое соединение извлекается из метод getConnection () интерфейса будет иметь отдельную конфигурацию. На самом деле я бы даже назвал это ошибкой, учитывая формулировки различных бит doco, которые я смотрел сегодня, и имена участвующих классов (например. DatabaseConfig, еще на соединение?).

во всяком случае, в разделах кода, таких как setup/teardown (пример ниже), вы даже не предоставляете объект подключения, поэтому я не вижу способа установить конфигурацию там.

dbTester.setDataSet(beforeData);
dbTester.onSetup();

в конце концов я просто расширенный JdbcDatabaseTester @ переопределить метод getConnection () и ввести конфигурацию, специфичную для MySQL каждый раз:

class MySQLJdbcDatabaseTester extends org.dbunit.JdbcDatabaseTester {
  public MySQLJdbcDatabaseTester(String driverClass, String connectionUrl, String username, String password,
                                 String schema) throws ClassNotFoundException {
    super(driverClass, connectionUrl, username, password, schema);
  }

  @Override
  public IDatabaseConnection getConnection() throws Exception {
    IDatabaseConnection connection = super.getConnection();
    DatabaseConfig dbConfig = connection.getConfig();
    dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
    dbConfig.setProperty(DatabaseConfig.PROPERTY_METADATA_HANDLER, new MySqlMetadataHandler());
    return connection;
  }
}

и, наконец, все ошибки ушли.


Я пришел сюда в поисках ответа на этот проблема. Для меня проблемой была стратегия именования Hibernate. Я понял, что это проблема, поскольку show_sql был истинным в приложении Spring.свойства:

spring.jpa.show-sql=true

я мог видеть сгенерированную таблицу SQL, и имя поля было "FACT_NUMBER" вместо "factNumber", которое у меня было в xml моего dbunit.

Это было решено, заставив стратегию именования по умолчанию (По иронии судьбы, по умолчанию кажется org.hibernate.cfg.ImprovedNamingStrategy, который кладет в '_'):

spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy

когда я получил эту ошибку, это было потому, что моя схема имела ограничение not null для столбца, но этот столбец отсутствовал в моем файле данных.

мой стол
<table name="mytable">
    <column>id</column>
    <column>entity_type</column>
    <column>deleted</column>
</table>

<dataset>
    <mytable id="100" entity_type"2"/>
</dataset>

у меня есть не нулевое ограничение на удаленный столбец, и когда я запускаю тест, я получаю исключение NoSuchColumnException.

когда я изменяю набор данных на

<mytable id="100" entity_type"2" deleted="0"/>

Я прошел мимо исключения.


Я столкнулся с этой проблемой, и причина заключалась в том, что dtd моего файла набора данных имел другое описание таблицы, в которую я хотел вставить данные.

поэтому проверьте, что ваша таблица, в которую вы хотите вставить данные, имеет те же столбцы, что и ваш dtd-файл.

когда я удаляю в dtd-файле столбец, которого не было в таблице, куда я вставил данные, проблема исчезла.


Ну в моем случае это был csv-файл, закодированный в UTF-8 с BOM char в начале. Я использовал блокнот для создания csv-файлов. Используйте notepade++, чтобы избежать сохранения BOM char.


У меня была та же проблема , а затем я понял, что использовал другое имя столбца в моей БД, чем то, что у меня внутри моего XML-файла.

Я уверен, что у вас есть проблема в user_id против USER_ID.


Я только что наткнулся на это сообщение об ошибке.

Мне пришлось расширить старый фрагмент кода - мне нужно было добавить новый столбец в несколько таблиц. В одной из моих сущностей, я забыл создать сеттер для этого столбца. Таким образом, вы можете проверить свои объекты, если они "завершены".

иногда это может быть так просто.


Ok я столкнулся с той же проблемой, и я нашел решение,то, как мы создаем тестовые данные, неправильно, для какого типа набора данных мы использовали, мы использовали набор данных xml, для которого следующий формат правильный, вы используете FlatXmlDataSet, тогда есть другой формат, для более подробного объяснения читайте по ссылке, приведенной ниже. XML должен быть в следующем формате.

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <table>
        <column>id</column>
        <column>name</column>
        <column>department</column>
        <column>startDate</column>
        <column>endDate</column>
        <row>
            <value>999</value>
            <value>TEMP</value>
            <value>TEMP DEPT</value>
            <value>2113-10-13</value>
            <value>2123-10-13</value>
        </row>
    </table>
</dataset>

Если вы хотите узнать больше, перейдите по этой ссылке : http://dbunit.sourceforge.net/components.html