DBunit 生成 java.lang.ClassCastException:尝试加载 CLOB 字段时无法将 java.lang.String 强制转换为 oracle.sql.CLOB
Posted
技术标签:
【中文标题】DBunit 生成 java.lang.ClassCastException:尝试加载 CLOB 字段时无法将 java.lang.String 强制转换为 oracle.sql.CLOB【英文标题】:DBunit generates java.lang.ClassCastException: java.lang.String cannot be cast to oracle.sql.CLOB when trying to load a CLOB field 【发布时间】:2011-01-26 01:36:15 【问题描述】:我在 Oracle 11GR2 上使用最新版本的 DBUnit (2.4.7)。我正在使用 Java 6 (1.6.0_15) 和最新版本的 Oracle 客户端 jar (jdbc6.jar)
我无法将 CLOB Oracle 字段引用的任何数据从 XML 文件成功加载到数据库中。
我用过各种版本的组合:
Oracle JDBC 库 ojdbc5.jar、ojdbc6.jar、oracle 10 jarsHibernate 库等...我认为问题在于 DBUnit。请参阅下面的堆栈跟踪。
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.0-CR-2</version>
和
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version>
我正在运行 Java 6、1.6.0_15。
我试过了:
1) FlatXmlDataSet 使用这个定义
<MESSAGE msg_id="1" mtp_id="1" msg_detail="asadds" />
2) XmlDataSet 使用这个定义
<table name="MESSAGE">
<column>MSG_ID</column>
<column>MTP_ID</column>
<column>MSG_DETAIL</column>
<row>
<value>1</value>
<value>1</value>
<value>dsad</value>
</row>
</table>
任何帮助将不胜感激!
堆栈跟踪如下:
在 org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:980) 错误 [10032010 14:15:13,031] - 创建 EntityManager 的异常:[] (MessageDAOTest.java:97) java.lang.RuntimeException:JpaDBTestCase 中的异常 在 com.ert.commons.junit4.hibernate.JpaDBTestCase.loadDbunitFiles(JpaDBTestCase.java:97) 在 com.ert.ertmon.dao.ejb.impl.MessageDAOTest.setUpBeforeClass(MessageDAOTest.java:94) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 在 org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:236) 在 org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62) 在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) 在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) 在 org.apache.maven.surefire.Surefire.run(Surefire.java:177) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:334) 在 org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:980) 原因:java.lang.ClassCastException:java.lang.String 无法转换为 oracle.sql.CLOB 在 oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:7898) 在 oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:7511) 在 oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:7984) 在 oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:237) 在 org.dbunit.dataset.datatype.ClobDataType.setSqlValue(ClobDataType.java:71) 在 org.dbunit.database.statement.SimplePreparedStatement.addValue(SimplePreparedStatement.java:73) 在 org.dbunit.database.statement.AutomaticPreparedBatchStatement.addValue(AutomaticPreparedBatchStatement.java:63) 在 org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:186) 在 org.dbunit.AbstractDatabaseTester.executeOperation(AbstractDatabaseTester.java:190) 在 org.dbunit.AbstractDatabaseTester.onSetup(AbstractDatabaseTester.java:103) 在 com.ert.commons.junit4.hibernate.JpaDBTestCase.loadDbunitFile(JpaDBTestCase.java:136) 在 com.ert.commons.junit4.hibernate.JpaDBTestCase.loadDbunitFiles(JpaDBTestCase.java:92) ... 21 更多【问题讨论】:
【参考方案1】:使用 org.dbunit.ext.oracle.Oracle10DataTypeFactory
在数据工厂配置中。
【讨论】:
这是正确的答案,但我遇到了 NCLOB 列的问题。这是因为 dbunit 仍然缺少 Oracle10DataTypeFactory 中的“nclob”案例。在手动将“nclob”案例添加到createDataType()
(类似于“clob”之一)方法 NCLOB 列也开始正常工作。看来 dbunit 正在消失,非常令人失望。【参考方案2】:
这看起来像Bug ID 1984596,我不太了解它的状态(它已关闭但......我不知道问题是否已解决)。您能否按照问题中的建议尝试使用 DbUnit 2.2.1(似乎是版本 2.2.2 中引入的更改导致了问题)。如果这可行,您绝对应该重新打开该问题。
【讨论】:
哇,感谢您的提示,它确实有效。我实际上在我的旅行中看到了那个页面,但由于它的年龄和引用的 DBunit 版本而被拒绝了。仅供参考,我需要将 org.dbunit.ext.oracle.Oracle10DataTypeFactory 恢复为 org.dbunit.ext.oracle.OracleDataTypeFactory(并进行其他更改),但现在 Clob 已成功加载 11G。我仍然无法相信我是唯一一个遇到此问题的人(在 Oracle 11G 中加载 CLOB),只要我的 SourceForge id 收到邮件,我就会更新上面列出的 BUG ID。再次,非常感谢! 已更新,让我们看看结果如何……不幸的是,这些天在 DBUnit 上似乎没有太多活动 @Paul 非常感谢您(反馈和努力)。是的,这很不幸(我个人非常喜欢 DbUnit)。 进一步更新...由于错误 1984596 被标记为已关闭,我打开了一个新错误以查看是否可以修复(再次)sourceforge.net/tracker/… @Paul Great (并且不复活那个旧错误确实更好,因为版本发生了变化等)。再次感谢您。【参考方案3】:前几天我在使用 Ant 和 DBUnit 时也遇到了这个问题。我正在使用 Ant 版本 1.7.1、DBUnit 2.4.5。和 Oracle 10g。我发现的“解决方法”是在 Ant 任务中指定数据库方言:
<dbunit driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin@127.0.0.1:1521:MyOracleDb" userid="[userid]" password="[password]" schema="[MySchema]">
<dbconfig>
<property name="datatypeFactory" value="org.dbunit.ext.oracle.OracleDataTypeFactory"/>
</dbconfig>
<operation type="CLEAN_INSERT" src="MY_DATA.xml" />
</dbunit>
添加 dbconfig 属性后,String / CLOB 转换问题就消失了。希望这可以帮助任何在 Ant 中看到此错误的人。
【讨论】:
我可以验证设置 datatypeFactory 是否有效。我们使用的是 2.4.8 并且遇到了同样的问题,但是指定 Oracle10DatatypeFactory 可以解决问题。然而,我们以编程方式完成了它,如下例所示:IDatabaseConnection conn = new DatabaseConnection(pConnection); DatabaseConfig config = conn.getConfig(); config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new org.dbunit.ext.oracle.Oracle10DataTypeFactory());
以上是关于DBunit 生成 java.lang.ClassCastException:尝试加载 CLOB 字段时无法将 java.lang.String 强制转换为 oracle.sql.CLOB的主要内容,如果未能解决你的问题,请参考以下文章
执行单元测试时如何防止dbunit生成database.script文件
DBunit 生成 java.lang.ClassCastException:尝试加载 CLOB 字段时无法将 java.lang.String 强制转换为 oracle.sql.CLOB