java.lang.ClassCastException:com.sun.proxy。$ Proxy45与oracle.sql.CLOB

时间:2017-04-03 11:57:44

标签: java oracle websphere jta hibernate3

需要专家的帮助。 我们使用的Hibernate版本:3.6.0.Final。 在oracle DB中保存hibernate Pojo后,一旦尝试在JTA事务下提交,就会出现以下错误:

  

来自before_completion同步操作的异常:   java.lang.ClassCastException:com.sun.proxy。$ Proxy45与。不兼容   oracle.sql.CLOB在   oracle.jdbc.driver.OraclePreparedStatement.setClob(OraclePreparedStatement.java:6236)     在   oracle.jdbc.driver.OraclePreparedStatementWrapper.setClob(OraclePreparedStatementWrapper.java:158)     在   com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.setClob(WSJdbcPreparedStatement.java:1845)     在   org.hibernate.type.descriptor.sql.ClobTypeDescriptor $ 1.doBind(ClobTypeDescriptor.java:60)     在   org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:89)     在   org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:282)     在   org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:277)     在   org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:85)     在   org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2166)     在   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2412)     在   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2856)     在   org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)     在org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)at at   org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)     在   org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)     在   org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)     在   org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)     在org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)at   org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)at   org.hibernate.transaction.synchronization.CallbackCoordinator.beforeCompletion(CallbackCoordinator.java:117)     在   org.hibernate.transaction.synchronization.HibernateSynchronizationImpl.beforeCompletion(HibernateSynchronizationImpl.java:51)     在   com.ibm.tx.jta.impl.RegisteredSyncs.coreDistributeBefore(RegisteredSyncs.java:291)     在   com.ibm.ws.tx.jta.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:153)     在   com.ibm.ws.tx.jta.TransactionImpl.prePrepare(TransactionImpl.java:2369)     在   com.ibm.ws.tx.jta.TransactionImpl.stage1CommitProcessing(TransactionImpl.java:577)     在   com.ibm.tx.jta.impl.TransactionImpl.processCommit(TransactionImpl.java:1015)     在   com.ibm.tx.jta.impl.TransactionImpl.commit(TransactionImpl.java:949)     在com.ibm.ws.tx.jta.TranManagerImpl.commit(TranManagerImpl.java:439)     在com.ibm.tx.jta.impl.TranManagerSet.commit(TranManagerSet.java:191)     在   com.ibm.ws.tx.jta.UserTransactionImpl.commit(UserTransactionImpl.java:302)     在   com.scania.webstars.scheduling.job.sla.SchedulingJobImportDataFromPAMPA.executeImportTask(SchedulingJobImportDataFromPAMPA.java:151)     在   com.scania.webstars.scheduling.job.sla.SchedulingJobImportDataFromPAMPA.timerExpired(SchedulingJobImportDataFromPAMPA.java:76)     在   com.ibm.ws.asynchbeans.timer.TimerImpl.callListenerMethod(TimerImpl.java:361)     在   com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:228)     在   com.ibm.ws.asynchbeans.J2EEContext $ RunProxy.run(J2EEContext.java:265)     在   java.security.AccessController.doPrivileged(AccessController.java:252)     在javax.security.auth.Subject.doAs(Subject.java:495)at   com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:132)at at   com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:90)at   com.ibm.ws.asynchbeans.J2EEContext $ DoAsProxy.run(J2EEContext.java:336)     在   java.security.AccessController.doPrivileged(AccessController.java:280)     在com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1174)at   com.ibm.ws.asynchbeans.timer.TimerImpl.runListenerAsCJWork(TimerImpl.java:490)     在com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:333)at   com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:230)at at   com.ibm.ws.util.ThreadPool $ Worker.run(ThreadPool.java:1862)

1 个答案:

答案 0 :(得分:1)

这里有几种可能性。 首先,请注意com.sun.proxy。$ Proxy45是一个动态代理类(请参阅java.lang.reflect.Proxy.getProxyClass / newProxyInstance)。 Hibernate正在调用其中一个JDBC API java.sql.PreparedStatement.setClob(...),该API接受java.sql.Clob参数,并且动态代理实例作为该参数提供。

应该注意的是,WebSphere Application Server不代理java.sql.Clob,并且似乎不太可能(尽管不是完全不可能)Oracle驱动程序也会这样做,所以我最好的猜测是Hibernate或者可能是代码调用Hibernate构建代理。从例外情况可以清楚地看出,Oracle JDBC驱动程序希望能够将参数(JDBC规范只需要java.sql.Clob)转换为oracle.sql.CLOB,这是一个特定于oracle的子类。 java.sql.Clob。见https://docs.oracle.com/database/121/JAJDB/oracle/sql/CLOB.html。看起来Oracle还定义了一个特定于供应商的接口,专门接受oracle.sql.CLOB https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OraclePreparedStatement.html#setCLOB_int__oracle_sql_CLOB_因此,Oracle驱动程序要求将特定于Oracle的oracle.sql.CLOB接口提供给JDBC标准java.sql.PreparedStatement.setClob(...,java.sql)似乎是错误的。 Clob)方法。无论如何,作为一个用户,你几乎无能为力。 Hibernate可以通过为oracle.sql.CLOB而不是java.sql.Clob构建动态代理来解决这个问题 - 如果它们还没有这样做,因为还有另一种可能导致此错误的可能性。如果您的应用程序,Hibernate和应用程序服务器中定义的JDBC提供程序之间有多个Oracle驱动程序副本,那么可能有两个来自不同类加载器的oracle.sql.CLOB类副本,这样这两个实例就是oracle.sql.CLOB类彼此不兼容,无法转换。要检查这是否是原因,请查看应用程序和应用程序服务器JDBC提供程序配置,共享库以及可能具有Oracle JDBC驱动程序的多个副本的任何其他位置(通常名为ojdbc * .jar)。如果您找到多个,切换到仅使用一个,并在一个地方。否则问题可能超出您的控制范围。