Org.dbunit.dataset.NoSuchColumnException

I get the following error while running my tests:

org.dbunit.dataset.NoSuchColumnException: myTable.MYFIELD - (Non-uppercase input column: myfield) in ColumnNameToIndexes cache map. Note that the map column names are NOT case sensitive. at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117) 

I set a breakpoint in org.dbunit.dataset.AbstractTableMetaData#getColumnIndex and found the following. In IntelliJ Idea, the method is as follows:

 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 column names are NOT case sensitive."); } } 

The value of this.getColumns() does not contain any Column with Column.columnName corresponding to the columnName parameter. Therefore, colIndex becomes null and an exception is thrown.

It looks like DBUnit is looking for the column index in the wrong table metadata.

How can i fix this?

Note. I inherited this code from someone else (did not write it).

+5
source share
2 answers

I am sensitive to the fact that you cannot share code. This makes things a little complicated, but here is an answer that I think is reasonable given the boundaries:

I was able to easily reproduce this exception using the minimal Spring Boot / DbUnit project cloned from GitHub . Perhaps my observations will make a hint that you are looking for, or at least inspire a better answer.

Steps

  • Clone the project and install the dependencies.
  • Run the HsqldbexampleApplicationTests.contextLoads() test. He passes.
  • Go into StaticResource.java and change one of the @Column annotations.

For example, I changed:

 @Column(name = "CONTENT") private String content; 

in

 @Column(name = "CONTENTZ") private String content; 
  • Repeat the test and note the exception
  • Alternatively, you can go to sampleData.xml and change the CONTENT attributes there (attribute name) to create the same exception.

Observations

  • The test gets its data from /META-INF/dbtest/sampleData.xml . Note the CONTENT attribute.
  • The resource has an @Column annotation, whose name must match the attribute found in the sampleData.xml elements.
  • Since your problem is with current tests, it may be that your code and .xml (?), Which moisten the test data store, are simply not in sync with the column name.

Further implication of the XML file?

My attempts to raise this exception by modifying queries and instance variable names were unsuccessful. Everything I tried made the compiler complain, so I excluded it.

For example, I also checked this repo and tried to change the request and the instance variable, but was ripped off by the compiler at every step. Change request:

Change request error

Change instance variable name:

Change variable name error

Where to looking for

  • Anywhere in any Java code where you have @Column with MYFIELD inside it. Remember that annotations can contain multiple lines in a file.
  • Any xml files containing MYFIELD .
  • Assuming your test code is working fine and your problems are limited to running tests, the main source of the suspect is the mechanism that enters data into your test. If it is not an xml file, what is it?
+2
source

It’s not clear from your message how you will get _columnsToIndexes This looks like part of the reflection code, which depends on your POJO. In this case, the migth problem is in initializing the Lazy object. Lazy initialized objects are not just an object object, but there may be a problem with the proxy server and its attempt to get its properties during reflection. You should probably try adding some unproxy createColumnIndexesMap method to you. Here is an example:

 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; } 

Of course it depends on your ORM, here is an example for Hibernate

+1
source

Source: https://habr.com/ru/post/1273322/


All Articles