簡體   English   中英

Unitils 數據庫異常

[英]Unitils database exception

在我的項目中,我使用 JDBC、MySQL、Servlets、JSP。 為了測試我的 dao,我做了一些單元測試,我正在嘗試使用 JUnit 和 Unitils。

我收到此異常:

    org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void com.jean.taxi.daoImpl.ClientDaoImplTest.testListModerators()
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:190)
    at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:791)
    at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273)
    at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:181)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:59)
    at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:42)
    at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:60)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:67)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
    at java.lang.String.startsWith(String.java:1385)
    at java.lang.String.startsWith(String.java:1414)
    at org.unitils.core.dbsupport.MySqlDbSupport.toCorrectCaseIdentifier(MySqlDbSupport.java:189)
    at org.unitils.core.dbsupport.DbSupport.init(DbSupport.java:97)
    at org.unitils.core.dbsupport.DbSupportFactory.getDbSupport(DbSupportFactory.java:77)
    at org.unitils.core.dbsupport.DbSupportFactory.getDefaultDbSupport(DbSupportFactory.java:56)
    at org.unitils.dbunit.DbUnitModule.getDefaultDbSupport(DbUnitModule.java:755)
    at org.unitils.dbunit.DbUnitModule.getDataSetFactory(DbUnitModule.java:725)
    at org.unitils.dbunit.DbUnitModule.getDataSetFactory(DbUnitModule.java:713)
    at org.unitils.dbunit.DbUnitModule.getDataSet(DbUnitModule.java:441)
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:261)
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:187)
    ... 21 more

我的 unitils-local.propreties:

database.userName=root
database.password=111111
database.storedIndentifierCase.mysql=mixed_case
dbUnit.datasetresolver.prefixWithPackageName=false
database.identifierQuoteString.mysql=none
database.schemaNames=TEST
database.dialect=mysql
database.driverClassName=com.mysql.jdbc.Driver

我的 unitils.properties:

# Name or path of the user specific properties file. This file should contain the necessary parameters to connect to the
# developer's own unit test schema. It is recommended to override the name of this file in the project specific properties
# file, to include the name of the project. The system will try to find this file in the classpath, the user home folder
# (recommended) or the local filesystem.
unitils.configuration.localFileName=unitils-local.properties

# Properties for the PropertiesDataSourceFactory
database.driverClassName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/test

database.schemaNames=test
# This property specifies the underlying DBMS implementation. Supported values are 'oracle', 'db2', 'mysql' and 'hsqldb'.
# The value of this property defines which vendor specific implementations of DbSupport and ConstraintsDisabler are chosen.
dbUnit.datasetresolver.prefixWithPackageName=false

我的數據集選項:

    <?xml version="1.0" encoding="UTF-8"?>
<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <CLIENT ID="1" CLIENT_NAME="clientName" CLIENT_LAST_NAME="clientLastName"
            EMAIL="email" ADDRESS="address" PASSWORD="password"
            PHONE="phone" SECOND_PHONE="secondPhone" THIRD_PHONE="thirdPhone" CREATE_DATE="2015-10-05 08:35:25"/>
    <CLIENT_GRANT ID="1" ID_CLIENT="1" ADMIN="0" MODERATOR="0" ACTIVE="1"/>
</dataset>

以及我正在嘗試測試的 test-dao 類的某些部分:

@Transactional(TransactionMode.ROLLBACK)
@DataSet("ClientDaoImplTest.xml")
public class ClientDaoImplTest extends UnitilsJUnit4 {
    @TestDataSource
    DataSource dataSource;

    ClientDaoImpl clientDao = null;
    ClientGrantDaoImpl clientGrantDao = null;

    @Before
    public void init() {
        clientDao = new ClientDaoImpl(dataSource);
        clientGrantDao = new ClientGrantDaoImpl(dataSource);
        TransactionHandlerImpl.setDataSource(dataSource);
        clientDao.setCurrentLocalConnection(ConnectionHolder.getLocalConnection());
        clientGrantDao.setCurrentLocalConnection(ConnectionHolder.getLocalConnection());
    }

    @After
    public void destroy() {
        clientDao = null;
        clientGrantDao = null;
    }

    @Test
    public void testAddNew() {
        final User user = new User();
        user.setEmail("email");
        user.setAddress("address");
        user.setPassword("password");
        user.setClientName("clientName");
        user.setClientLastName("clientLastName");
        user.setPhone("phone");
        final ClientGrant clientGrant = user.getClientGrant();
        clientGrant.setClientId(user.getId());
        clientGrant.setActive(true);
        user.setClientGrant(clientGrant);
        executeTest(new Transaction<Long>() {
            @Override
            public void doTransaction() throws Exception {
                Long clientId = clientDao.addNew(user);
                user.setId(clientId);
                clientGrantDao.addNew(user.getClientGrant());
                assertTrue(assertClient(clientDao.get(clientId), user));
            }
        });
    }

我知道我的數據庫選項有問題。 你能幫我找到解決這個問題的方法嗎? 謝謝。

更新:更改我的 unitils-local.properties 中的參數后:來自:

database.identifierQuoteString.mysql=none

到:

database.identifierQuoteString.mysql=auto

a 有一個新的例外:

org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void com.jean.taxi.daoImpl.ClientDaoImplTest.testAddNew()
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:190)
    at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:791)
    at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273)
    at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:181)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:59)
    at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:42)
    at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:60)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:67)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy
    at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:46)
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:342)
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:268)
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:187)
    ... 21 more
Caused by: org.dbunit.dataset.NoSuchColumnException: client.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:143)
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
    at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
    at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
    ... 24 more

也許有一些新的變體或關於這個問題的一些想法? 謝謝。

我會說問題出在這里:

database.identifierQuoteString.mysql=none

嘗試將其設置為以下內容:

database.identifierQuoteString.mysql=auto

最終,類MySqlDbSupport中有一個bug。 如果在屬性文件中將database.identifierQuoteString.mysql屬性設置為none ,則將DbSupport類中名為identifierQuoteString的私有字段設置為null。 toCorrectCaseIdentifier中的toCorrectCaseIdentifier方法獲取此字段的值,但是在將其傳遞給String.startsWith之前忘記進行空檢查。 因此,我們得到一個NullPointerException。

使用auto向數據庫詢問要使用的標識符-引號字符串。 我不明白為什么您會想要使用除此以外的任何東西。

在MySQL數據庫中使用unitils時,我遇到了同樣的問題。 解決方案是配置一個MySQL元數據處理程序:

org.dbunit.database.IMetadataHandler.implClassName=org.dbunit.ext.mysql.MySqlMetadataHandler

我知道這個問題已經很久了,Unitils不再得到維護,但可以幫助別人。

在我的情況下,解決方案是將此行添加到屬性中:

unitils.module.dbunit.className=org.dbunit.MySqlDbUnitModule

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM