Issue Type: Bug Bug
Assignee: Unassigned
Components: core
Created: 14/Nov/12 8:43 AM
Description:

After updating from 4.1.5 to 4.1.8 we get an AbstractMethodError

java.lang.AbstractMethodError: com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy75.setBinaryStream(Unknown Source)
at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$4$1.doBind(BlobTypeDescriptor.java:163)
at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$1$1.doBind(BlobTypeDescriptor.java:86)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:280)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:275)
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2747)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3025)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3469)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)

After having a closer look at the code I think i have figured out what causes this. The code tries to call PrepareStatement.setBinaryStream(int, InputStream, long). This method was added in JDK1.6 but C3P0 implements just the JDK1.5 API and there it just exists as (int, InputStream, int). But as far as I know Hibernate doesn't require JDK 1.6

The first idea was that BlobTypeDescriptor was changed. But that was not true.

public static final BlobTypeDescriptor STREAM_BINDING =
			new BlobTypeDescriptor() {
				@Override
                public <X> BasicBinder<X> getBlobBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
					return new BasicBinder<X>( javaTypeDescriptor, this ) {
						@Override
						protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
								throws SQLException {
							final BinaryStream binaryStream = javaTypeDescriptor.unwrap( value, BinaryStream.class, options );
							st.setBinaryStream( index, binaryStream.getInputStream(), binaryStream.getLength() );
						}
					};
				}

				@Override
                public <X> BasicExtractor<X> getBlobExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {
					return new BasicExtractor<X>( javaTypeDescriptor, this ) {
						@Override
						protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
							return javaTypeDescriptor.wrap( rs.getBinaryStream( name ), options );
						}
					};
				}
			};

But after some time I figure out that signature of BinaryStream.getLength() was changed so that it returns an long instead of an int now. When you compile BlobTypeDescriptor with the new BinaryStream class that works well but it means that it will try to call a different JDBC API now. And this API doesn't exist in JDK 1.5 yet.

This is a smilar problem like in HHH-7778

Environment: Hibernate 4.1.8, c3p0, MSSQL
Project: Hibernate ORM
Priority: Critical Critical
Reporter: Emanuel Kupcik
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira