6

运行测试时出现以下错误:

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()不包含任何ColumnColumn.columnName参数匹配的内容columnName。因此colIndex变为null并抛出异常。

看起来 DBUnit 正在错误的表元数据中查找列索引。

我怎样才能解决这个问题?

注意:我从其他人那里继承了这段代码(不是写的)。

4

2 回答 2

4

我对您无法真正共享代码这一事实很敏感。这确实让事情变得有点困难,但考虑到限制,我认为这是一个合理的答案:

我能够使用从 GitHub 克隆的最小 Spring Boot/DbUnit 项目轻松重现此异常。也许我的观察将相当于您正在寻找的提示,或者至少会激发一个更好的答案。

脚步

  • 克隆项目并安装依赖项。
  • 运行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文件的进一步含义?

我试图通过更改查询和实例变量名称来引发此异常的尝试没有成功。我尝试的一切都让编译器抱怨,所以我排除了它。

例如,我还检查了这个 repo,并尝试更改查询和实例变量,但在每一步都被编译器阻止。更改查询:

更改查询错误

更改实例变量名称:

更改变量名错误

在哪里看

  • @Column在您拥有的任何 Java 代码中的任何位置MYFIELD。请记住,注释可以跨越文件中的多行。
  • 任何包含MYFIELD.
  • 假设被测代码运行良好,并且您的问题仅限于运行测试,那么将数据注入测试的机制是主要嫌疑人。如果这不是xml 文件,它是什么?
于 2017-11-19T00:34:03.180 回答
1

从您的帖子中不清楚您如何获得_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 的例子

于 2017-11-20T20:16:59.193 回答