org.dbunit.dataset.NoSuchColumnException
Posted
技术标签:
【中文标题】org.dbunit.dataset.NoSuchColumnException【英文标题】: 【发布时间】:2018-04-26 03:43:40 【问题描述】:我在运行测试时遇到以下错误:
: 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 在错误的表元数据中寻找列索引。
我该如何解决这个问题?
注意:我从别人那里继承了这段代码(不是写的)。
【问题讨论】:
既然您已经对问题进行了详细分析,我想问这个问题的最佳地点是非 DBUnit 支持论坛。 有两个可能的原因。 DBUnit 是错误的。或者,您在某些注释中提供了错误的 columnName 或错误命名的 getter/setter 对。 您需要显示更多的代码,以便有人更好地了解情况。另外,在您的情况下使用了哪个表,您是否检查过它的来源? @TarunLalwani 我到底能找到什么? 这是一个 JPA 项目吗?测试数据库是如何创建的?另请参阅此处以启用所有正在生成的 SQL 的日志记录,包括表创建和 iserts ***.com/a/19299769/1356423 【参考方案1】:我对您无法真正共享代码这一事实很敏感。这确实让事情变得有些困难,但考虑到限制,我认为这是一个合理的答案:
我能够使用minimal Spring Boot/DbUnit project cloned from GitHub 轻松重现此异常。也许我的观察会成为您正在寻找的提示,或者至少会激发出更好的答案。
步骤
克隆 the project 并安装依赖项。 运行HsqldbexampleApplicationTests.contextLoads()
测试。它通过了。
进入StaticResource.java
,并更改@Column
注释之一。
比如我改了:
@Column(name = "CONTENT")
private String content;
到:
@Column(name = "CONTENTZ")
private String content;
再次运行测试并观察异常
或者,您可以进入sampleData.xml
并更改那里的CONTENT
属性(属性name),以产生相同的异常。
观察
测试从/META-INF/dbtest/sampleData.xml
获取数据。注意CONTENT
属性。
资源具有@Column
注释,其name
必须与sampleData.xml
元素中的属性匹配。
由于您的问题还在于运行测试,可能是您的代码和为您的测试数据存储提供水分的.xml
(?) 在列名方面完全不同步。
XML 文件的进一步含义?
我尝试通过更改查询和实例变量名称来引发此异常,但没有成功。我尝试的一切都让编译器抱怨,所以我排除了它。
例如,我还检查了this repo,并尝试更改查询和实例变量,但在每一步都被编译器阻挠。更改查询:
更改实例变量名称:
去哪里看
在你有@Column
和MYFIELD
的任何Java 代码中的任何地方。请记住,注释可以跨越文件中的多行。
任何包含MYFIELD
的xml文件。
假设被测代码工作正常,并且您的问题仅限于运行测试,那么将数据注入测试的机制是主要的怀疑对象。如果这个不是一个xml文件,它是什么?
【讨论】:
【参考方案2】:您的帖子不清楚您如何获得_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 的例子
【讨论】:
以上是关于org.dbunit.dataset.NoSuchColumnException的主要内容,如果未能解决你的问题,请参考以下文章