16

在发布此内容之前,我搜索了一下,我在 dbunit-user 档案中查找了一些内容,还在 DbUnit 错误列表中查找了一些内容,但我没有找到要查找的内容。不幸的是,这里的答案也没有帮助我。

我使用 DbUnit 2.4.8 和 MySQL 5.1.x 在 setUp 中填充一些 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

执行 REFRESH 作为数据库设置操作会引发以下异常。

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 回答后编辑

我正在使用 aPropertiesBasedJdbcDatabaseTester来配置我的 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();
4

9 回答 9

6

我今天遇到了类似的问题(使用 v2.2 中添加的针对 MySQL 的 IDatabaseTester 接口)并花了几个小时来解决这个问题。OP 使用的是 PropertiesBasedJdbcDatabaseTester,而我使用的是它的“父”JdbcDatabaseTester。

DBUnit 有一个与此 NoSuchColumnException(特定于 MySQL)相关的常见问题解答,但对我来说似乎是一个疏忽,它忽略了从接口的 getConnection() 方法中提取的每个连接都将具有单独的配置。事实上,考虑到我今天看到的各种 doco 的措辞以及所涉及的类的名称(例如 DatabaseConfig,但每个连接?),我什至将其称为 bug。

无论如何,在 setup/teardown 之类的代码部分(下面的示例)中,您甚至没有提供 Connection 对象,因此我看不到在其中设置配置。

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

最后,我只是将 JdbcDatabaseTester 扩展为 @Override 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;
  }
}

最后所有的错误都消失了。

于 2014-01-06T06:17:48.867 回答
4

我有理由相信问题源于user_id作为记录 ID 的列。过去我有类似的问题,行 ID 是由 SQL Server 本地生成的。我现在不在办公桌前,但试试这个解决方案,看看它是否有帮助: http: //old.nabble.com/case-sensitive-on-tearDown--td22964025.html

更新 - 2011 年 2 月 3 日

我在这里有一个可行的解决方案。这是我的测试代码:-

MySQL 脚本

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 '',
       PRIMARY KEY (`user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=14

dbunit-test.xml 测试文件

<?xml version='1.0' encoding='UTF-8'?>

<dataset>
    <jforum_users user_id="100" username="First User" />
</dataset>

Java 代码

Class.forName("com.mysql.jdbc.Driver");
Connection jdbcConnection = DriverManager.getConnection("jdbc:mysql://localhost:8889/test", "", "");
IDatabaseConnection con = new DatabaseConnection(jdbcConnection);

InputStream is = getClass().getClassLoader().getResourceAsStream("dbunit-test.xml");
IDataSet dataSet = new FlatXmlDataSetBuilder().build(is);
DatabaseOperation.CLEAN_INSERT.execute(con, dataSet);

con.close();

我没有收到任何错误,并且该行已添加到数据库中。

仅供参考,我确实尝试过REFRESH,而且效果也很好,没有错误:-

DatabaseOperation.REFRESH.execute(con, dataSet);

我正在使用 DBUnit 2.4.8 和 MySQL 5.1.44。

希望这可以帮助。

于 2011-02-03T03:12:57.553 回答
2

我来这里是为了寻找这个问题的答案。对我来说,问题是休眠命名策略。我意识到这是问题所在,因为在 Spring 的 application.properties 中 show_sql 是正确的:

spring.jpa.show-sql=true

我可以看到生成的表 SQL 并且字段名称是 'FACT_NUMBER' 而不是我在 dbunit 的 xml 中的 'factNumber'。

这是通过强制使用默认命名策略来解决的(具有讽刺意味的是,默认值似乎是org.hibernate.cfg.ImprovedNamingStrategy,它放入了 '_'):

spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
于 2015-04-01T01:54:32.757 回答
2

当我收到此错误时,这是​​因为我的架构对列有非空约束,但我的数据文件中缺少此列。

例如,我的桌子有

<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"/>

我克服了异常。

于 2017-03-20T12:34:04.350 回答
0

我遇到了这个问题,原因是我的数据集文件的 dtd 的描述与我想要插入数据的表不同。

因此,请检查要插入数据的表是否与 dtd 文件具有相同的列。

当我在 dtd 文件中删除不在我插入数据的表中的列时,问题消失了。

于 2015-11-26T13:10:20.513 回答
0

好吧,就我而言,它是一个以 UTF-8 编码的 csv 文件,开头带有 BOM char。我正在使用记事本创建 csv 文件。使用 notepad++ 避免保存 BOM 字符。

于 2016-11-01T12:56:50.993 回答
0

我有同样的问题,然后认为我在数据库中使用的列名与我在 XML 文件中使用的列名不同。

我确定您在 user_id 与 USER_ID 中遇到了问题。

于 2017-05-10T16:08:12.267 回答
0

我刚刚偶然发现了这个错误消息。

我不得不扩展一段旧代码——我需要向几个表中添加一个新列。在我的一个实体中,我忘记为此列创建一个设置器。因此,您可以检查您的实体是否“完整”。

有时它可能就这么简单。

于 2018-03-13T12:18:21.763 回答
-1

好的,我遇到了同样的麻烦,我找到了解决方案,我们创建测试数据的方式是错误的,对于我们使用的是哪种数据集,我们使用的是以下格式正确的 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

于 2013-11-21T09:40:43.313 回答