DBUnit test gives NoSuchColumnException for MariaDB

馋奶兔 提交于 2021-01-28 10:33:18

问题


The important thing to notice that these tests work perfect on Ubuntu and on Server, but fail with the same error on Mac and Windows.

So, in my test I use this configuration for connection to Maria db:

@Configuration
public class EmbeddedDatabase {

    @Autowired
    private String defaultSchema;

    @Bean
    public MariaDB4jService mariaDB4jService() {
        MariaDB4jSpringService mariaDB4jSpringService = new MariaDB4jSpringService();

        DBConfigurationBuilder config = mariaDB4jSpringService.getConfiguration();
        config.setPort(3310);

        return mariaDB4jSpringService;
    }

    @Bean
    public DataSource dataSource(MariaDB4jService mariaDB4jService) throws Exception {
        mariaDB4jService.getDB().createDB(defaultSchema);

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(mariaDB4jService.getConfiguration().getURL(defaultSchema));
        dataSource.setUsername("root");
        dataSource.setPassword("");
        dataSource.setDriverClassName("org.mariadb.jdbc.Driver");

        return dataSource;
    }
}

Now, the default schema is set in my xml configuration file and it's:

<bean id="dbUnitDatabaseConnection" class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean" 
    <property name="schema" ref="defaultSchema" />
    <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="defaultSchema" class="java.lang.String">
    <constructor-arg type="java.lang.String" value="test"/>
</bean>

Here is the parent class for all test classes:

@ContextConfiguration("classpath:test-repository-config.xml")
@TestExecutionListeners({ DbUnitTestExecutionListener.class })
@DbUnitConfiguration(dataSetLoader = RepositoryFlatXmlDataSetLoader.class)
public abstract class AbstractRepositoryTest 
    extends AbstractTransactionalJUnit4SpringContextTests {

}

I have this custom RepositoryFlatXmlDataSetLoader for replacement "[NULL]" fields which I'm using in my xml dataset:

public class RepositoryFlatXmlDataSetLoader extends AbstractDataSetLoader {
    private static Logger logger = LoggerFactory.getLogger(RepositoryFlatXmlDataSetLoader.class);
    @Override
    protected IDataSet createDataSet(Resource resource) throws Exception {
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        builder.setColumnSensing(true);

        try (InputStream inputStream = resource.getInputStream()) {
            return createReplacementDataSet(builder.build(inputStream));            
        }
        catch(Throwable thrh){
            logger.error("Failed to create dataset");
            throw thrh;
        }
    }

    private ReplacementDataSet createReplacementDataSet(FlatXmlDataSet dataSet) {
        ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);

        //Configure the replacement dataset to replace '[null]' strings with null.
        replacementDataSet.addReplacementObject("[null]", ITable.NO_VALUE);
        replacementDataSet.addReplacementObject("[NULL]", ITable.NO_VALUE);

        return replacementDataSet;
    }
}

This is one of my dataset xml files - officeRepositoryData.xml:

<dataset>
    <cfr_office ID="1" ORG_NAME="demo" IS_DEFAULT="true"/>
    <cfr_office ID="2" ORG_NAME="test" IS_DEFAULT="false"/>
</dataset>

For example, this is the one of the tests:

@NotThreadSafe
@DatabaseSetup(value = "officeRepositoryData.xml", type = DatabaseOperation.CLEAN_INSERT)
@DatabaseTearDown(value = "officeRepositoryData.xml", type = DatabaseOperation.DELETE_ALL)
public class OfficeRepositoryTest extends AbstractRepositoryTest {

    @Autowired
    private OfficeRepository officeRepository;

    @Test
    public void testDefaultOfficeFound() {
        List<Office> offices = officeRepository.findDefault();

        assertTrue(isNotEmpty(offices));

        Office office = offices.get(0);
        assertEquals("demo", office.getOrganizationName());
        assertTrue(office.getIsDefault());
    }
}

So, what happens when I'm running my tests... All the tables are created in JPA, I see it in the eclipse console and in the DB Perspective with MariaDB connection created, then when dbUnit starts to prepare th dataset for the test I get an error. This is the stack trace for it with some previous lines which can be important(or not, not sure):

INFO  o.s.t.c.t.TransactionContext - Began transaction (1) for test context [DefaultTestContext@305e95a4 testClass = OfficeRepositoryTest, testInstance = com.sumac.nots.repository.api.OfficeRepositoryTest@55e42684, testMethod = testDefaultOfficeFound@OfficeRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2a5c6b76 testClass = OfficeRepositoryTest, locations = '{classpath:test-repository-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@7f22687e]; rollback [true]
11:49:33.775 [main] WARN  o.d.d.AbstractTableMetaData - Potential problem found: The configured data type factory 'class org.dbunit.dataset.datatype.DefaultDataTypeFactory' might cause problems with the current database 'MySQL' (e.g. some datatypes may not be supported properly). In rare cases you might see this message because the list of supported database products is incomplete (list=[derby]). If so please request a java-class update via the forums.If you are using your own IDataTypeFactory extending DefaultDataTypeFactory, ensure that you override getValidDbProducts() to specify the supported database products.
11:49:42.306 [main] WARN  o.d.d.DatabaseTableMetaData - No columns found for table 'cfr_office' that are supported by dbunit. Will return an empty column list
11:49:48.098 [main] WARN  o.s.t.c.TestContextManager - Caught exception while allowing TestExecutionListener [com.github.springtestdbunit.DbUnitTestExecutionListener@66d3eec0] to process 'before' execution of test method [public void com.sumac.nots.repository.api.OfficeRepositoryTest.testDefaultOfficeFound()] for test instance [com.sumac.nots.repository.api.OfficeRepositoryTest@55e42684]
org.dbunit.dataset.NoSuchColumnException: cfr_office.ID -  (Non-uppercase input column: 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.AbstractBatchOperation.execute(AbstractBatchOperation.java:150)
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
    at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:183)
    at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:75)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:185)
    at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:269)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)

Often for such an error the reason is the column is missed somewhere or there are some case sensitivity problems with the column, I was debugging deeply in the code, and it seems to me that for this particular case I faced some other problem. But I'm not sure.

It looks like deep in the code dbUnit creates some columnList, getting some info about the db from some resultSet. It feels this column list with column values in case if all the info matches for the catalog, schema_name and table_name. But shema_name is null in the debug, so it fails to create the column list, and then fails to find there the very first column - which is ID. If the last paragraph I've written is a mess, don't take it in a count.


回答1:


I'd try lower-case column names:

<dataset>
    <cfr_office id="1" org_name="demo" is_default="true"/>
    <cfr_office id="2" org_name="test" is_default="false"/>
</dataset>


来源:https://stackoverflow.com/questions/50879256/dbunit-test-gives-nosuchcolumnexception-for-mariadb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!