2
votes

In need of help from experts. Hibernate version we use: 3.6.0.Final. After saving the hibernate Pojo in oracle DB and once trying to commit under JTA transaction, the below error occurs:

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

1
Hello Can you please debug and see what object you are getting .If u get java.sql.Clob then you need to convert your reference to java.sql.Clob instead of oracle.sql.CLOBPradeep
Hi, org.hibernate.engine.jdbc.ClobProxy@7acb38f3 this is the object getting after saving to DB and before transaction commit. ThanksReddeiah Malepati

1 Answers

1
votes

There are a couple of possibilities here. First, note that com.sun.proxy.$Proxy45 is a dynamic proxy class (see java.lang.reflect.Proxy.getProxyClass/newProxyInstance). Hibernate is invoking one of the JDBC APIs java.sql.PreparedStatement.setClob(...) which accepts a java.sql.Clob parameter, and a dynamic proxy instance is being supplied as that parameter.

It should be noted that WebSphere Application Server does not proxy java.sql.Clob, and it seems unlikely (although not entirely impossible) that the Oracle driver would do so either, so my best guess is that Hibernate or possibly code that invokes Hibernate is constructing the proxy. It's clear from the exception that the Oracle JDBC driver expects to be able to cast the parameter (which JDBC spec only requires to be java.sql.Clob) to oracle.sql.CLOB, which is an oracle-specific subclass of java.sql.Clob. See https://docs.oracle.com/database/121/JAJDB/oracle/sql/CLOB.html. It looks like Oracle also defines a vendor specific interface specifically to accept oracle.sql.CLOB https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OraclePreparedStatement.html#setCLOB_int__oracle_sql_CLOB_ so it certainly seems wrong for the Oracle driver to be requiring that the Oracle-specific oracle.sql.CLOB interface be supplied to the JDBC standard java.sql.PreparedStatement.setClob(..., java.sql.Clob) method. In any case, as a user, there is little you can do about that. Hibernate could potentially work around this by constructing the dynamic proxy for oracle.sql.CLOB rather than java.sql.Clob -- if they aren't doing so already, as there is one other possibility that could cause this error. If you have multiple copies of the Oracle driver between your application, Hibernate, and the JDBC provider defined in the application server, there could be two copies of the oracle.sql.CLOB class coming from different classloaders, such that these two instances of the oracle.sql.CLOB class are incompatible with each other and would fail to cast. To check if this might be the cause, look through your applications and your application server JDBC provider configuration, shared libraries, and anywhere else that you might have multiple copies of the Oracle JDBC driver (usually named ojdbc*.jar). If you find multiple, switching to only using one, and in one single place. Otherwise the problem is likely outside of your control.