DbUnit:NoSuchColumnException 和区分大小写
在发布这篇文章之前,我用谷歌搜索了一下,我在 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 回答后进行编辑
我正在使用 PropertiesBasedJdbcDatabaseTester
来配置我的 DbUnit 环境,如下所示:
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();
Before posting this I googled a bit, I looked for in dbunit-user
archives and a bit also in DbUnit bug list, but I'm not found what
looking for.
Unfortunately, answers here did not help me either.
I'm using DbUnit 2.4.8 with MySQL 5.1.x to populate in setUp some JForum tables.
The issue is first appearing on jforum_users table created by this script
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
Executing REFRESH as database setup operation the following exception is raised.
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)
I looked in AbstractTableMetaData.java
sources and nothing seems -statically- wrong.
The method
private Map createColumnIndexesMap(Column[] columns)
uses
columns[i].getColumnName().toUpperCase()
in writing map keys.
And then the method
public int getColumnIndex(String columnName)
uses
String columnNameUpperCase = columnName.toUpperCase();
Integer colIndex = (Integer) this._columnsToIndexes.get(columnNameUpperCase);
to read object from the map.
I really can't undestand what's going on...
Anybody can help me please?
Edit after last @limc answer
I'm using a PropertiesBasedJdbcDatabaseTester
to configure my DbUnit env, as follow:
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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我今天遇到了与此类似的问题(使用 v2.2 中添加的针对 MySQL 的 IDatabaseTester 接口),并花了几个小时来解决它。 OP正在使用PropertiesBasedJdbcDatabaseTester,而我正在使用它的“父级”JdbcDatabaseTester。
DBUnit 有 与此 NoSuchColumnException 相关的常见问题解答(特定于 MySQL),但它看起来像对我来说,它忽略了提及从 接口的 getConnection() 方法 将有单独的配置。事实上,鉴于我今天查看的 doco 的各个部分的措辞以及所涉及的类的名称(例如 DatabaseConfig,但每个 Connection?),我什至将其称为 bug。
无论如何,在像设置/拆卸(下面的示例)这样的代码部分中,您甚至没有提供 Connection 对象,因此我无法在其中设置配置。
最后,我只是将 JdbcDatabaseTester 扩展为 @Override getConnection() 方法,并每次注入特定于 MySQL 的配置:
最后所有错误都消失了。
I had a similar problem to this today (using the IDatabaseTester interface added in v2.2 against MySQL) and spent several hours tearing my hair out over it. The OP is using a PropertiesBasedJdbcDatabaseTester, whilst I was using its 'parent' JdbcDatabaseTester.
DBUnit has a FAQ answer related to this NoSuchColumnException (specific to MySQL) but it looks like an oversight to me that it neglects to mention that each connection drawn from the interface's getConnection() method will have separate config. In fact I'd go so far as to call it bug given the wording of the various bits of doco I looked at today and the names of the classes involved (eg. DatabaseConfig, yet per Connection?).
Anyway, in sections of code like setup/teardown (example below) you don't even provide the Connection object so there's no way I could see to set the config in there.
In the end I just extended JdbcDatabaseTester to @Override the getConnection() method and inject the configuration specific to MySQL each time:
And finally all the errors went away.
我有理由相信问题源于
user_id
列作为记录 ID。我过去也遇到过类似的问题,行 ID 是由 SQL Server 本机生成的。我现在不在办公桌前,但尝试此解决方案看看是否有帮助: http://old.nabble.com/case-sensitivity-on-tearDown--td22964025.html更新 - 02-03-11
我在这里有一个可行的解决方案。这是我的测试代码:-
MySQL 脚本
dbunit-test.xml 测试文件
Java 代码
我没有收到任何错误,该行是添加到数据库中。
仅供参考,我确实尝试了 REFRESH,并且效果也很好,没有错误:-
我正在使用 DBUnit 2.4.8 和 MySQL 5.1.44。
希望这有帮助。
I have reason to believe the problem stemmed from
user_id
column as the record ID. I have similar problem in the past where the row ID is generated natively by SQL Server. I'm not at my work desk now, but try this solution to see if it helps: http://old.nabble.com/case-sensitivity-on-tearDown--td22964025.htmlUPDATE - 02-03-11
I have a working solution here. Here's my test code:-
MySQL Script
dbunit-test.xml Test File
Java Code
I didn't get any errors, and the row was added into the database.
Just FYI, I did try a
REFRESH
and that works fine without errors too:-I'm using DBUnit 2.4.8 and MySQL 5.1.44.
Hope this helps.
我来这里是为了寻找这个问题的答案。对我来说,问题是 Hibernate 命名策略。我意识到这是问题所在,因为 Spring 的 application.properties 中的 show_sql 是正确的:
我可以看到生成的表 SQL,并且字段名称是“FACT_NUMBER”,而不是我在 dbunit 的 xml 中的“factNumber”。
这是通过强制使用默认命名策略来解决的(具有讽刺意味的是,默认值似乎是 org.hibernate.cfg.ImprovedNamingStrategy,其中包含“_”):
I came here looking for an answer to this problem. For me the problem was the Hibernate Naming Strategy. I realised this is the problem as show_sql was true in the Spring's application.properties:
I could see the generated table SQL and the field name was 'FACT_NUMBER' instead of 'factNumber' I had in my dbunit's xml.
This was solved by forcing the default naming strategy (ironically the default seems to be
org.hibernate.cfg.ImprovedNamingStrategy
, which puts in the '_'):当我收到此错误时,这是因为我的架构对列有非空约束,但我的数据文件中缺少该列。
例如,我的表
对已删除的列有非空约束,当我运行测试时,我得到 NoSuchColumnException。
当我将数据集更改为时,
我就克服了异常。
When I got this error, it was because my schema had a not null constraint on a column, but this column was missing from my datafile.
For example, my table had
I have a not null constraint on the deleted column and when I run the test, I get the NoSuchColumnException.
When I change the dataset to
I get past the Exception.
就我而言,它是一个以 UTF-8 编码的 csv 文件,开头带有 BOM 字符。我正在使用记事本创建 csv 文件。使用notepade++来避免保存BOM字符。
Well in my case it was a csv file encoded in UTF-8 with BOM char in the beginning. I was using notepad to create csv files. Use notepade++ to avoid saving BOM char.
我遇到了这个问题,原因是我的数据集文件的 dtd 的描述与我想要插入数据的表不同。
因此,请检查要插入数据的表是否具有与 dtd 文件相同的列。
当我在 dtd 文件中删除不在插入数据的表中的列时,问题就消失了。
I was faced with this problem and the reason was that the dtd of my dataset file had a description different of the table where i wanted to insert data.
So check that your table where you want to insert data has the same columns that your dtd file.
when I delete in the dtd file the column that was not in the table where i inserted the data the problem disappeared.
我遇到了同样的问题,然后我发现我在数据库中使用的列名称与 XML 文件中的列名称不同。
我确信您在 user_id 与 USER_ID 方面遇到问题。
I had same problem , then figured I have used different column name in my DB than what I have inside my XML file.
I'm sure you got problem in user_id vs USER_ID.
我刚刚被这个错误消息绊倒了。
我必须扩展一段旧代码 - 我需要向几个表添加一个新列。在我的一个实体中,我忘记为此列创建一个setter。因此,您可以检查您的实体是否“完整”。
有时可能就是这么简单。
I've just stumbled my self over this error message.
I had to extend an old piece of code - I needed to add a new column to several tables. In one of my entities I've forgotten to create a setter for this column. So you might check your entities if they are "complete".
Sometimes it might be as simple as that.
好吧,我遇到了同样的麻烦,我找到了解决方案,我们创建测试数据的方式是错误的,对于我们使用的哪种数据集,我们使用的是 xml 数据集,以下格式是正确的,您正在使用FlatXmlDataSet 则有一种不同的格式,有关更多说明,请阅读下面提供的链接。 xml 应采用以下格式。
如果您想了解更多信息,请访问此链接:http://dbunit.sourceforge.net/components.html< /a>
Ok I faced the same trouble and I found the solution, The way we are creating the test data is wrong,for what kind of data set we were using, We were using the xml data set for which following format is correct is you are using the FlatXmlDataSet then there is a different format, for more explanation read in the link provided below. the xml should be in following format.
If you wish to know more go to this link : http://dbunit.sourceforge.net/components.html