2016-04-12 7 views
0

Я использую Hibernate 5.0.7 и PostgreSql в своем приложении. Кроме того, у меня есть таблица с двойным столбцом типа данных. Для отображения этого поля с Hibernate в моей сущности, я создал класс, который реализует интерфейс UserType:Пользовательский двойной [] UserType with Hibernate

import org.apache.commons.lang3.ArrayUtils; 
import org.hibernate.HibernateException; 
import org.hibernate.engine.spi.SessionImplementor; 
import org.hibernate.usertype.UserType; 

import java.io.Serializable; 
import java.sql.*; 

public class DoubleArrayUserType implements UserType { 
    protected static final int SQLTYPE = java.sql.Types.ARRAY; 

    @Override 
    public Object nullSafeGet(final ResultSet rs, final String[] names, final SessionImplementor sessionImplementor, final Object owner) throws HibernateException, SQLException { 
     Array array = rs.getArray(names[0]); 
     Double[] javaArray = (Double[]) array.getArray(); 
     return ArrayUtils.toPrimitive(javaArray); 
    } 

    @Override 
    public void nullSafeSet(final PreparedStatement statement, final Object object, final int i, final SessionImplementor sessionImplementor) throws HibernateException, SQLException { 
     Connection connection = statement.getConnection(); 

     double[] castObject = (double[]) object; 
     Double[] doubles = ArrayUtils.toObject(castObject); 
     Array array = connection.createArrayOf("DOUBLE", doubles); 

     statement.setArray(i, array); 
    } 

    @Override 
    public Object assemble(final Serializable cached, final Object owner) throws HibernateException { 
     return cached; 
    } 

    @Override 
    public Object deepCopy(final Object o) throws HibernateException { 
     return o == null ? null : ((double[]) o).clone(); 
    } 

    @Override 
    public Serializable disassemble(final Object o) throws HibernateException { 
     return (Serializable) o; 
    } 

    @Override 
    public boolean equals(final Object x, final Object y) throws HibernateException { 
     return x == null ? y == null : x.equals(y); 
    } 

    @Override 
    public int hashCode(final Object o) throws HibernateException { 
     return o == null ? 0 : o.hashCode(); 
    } 

    @Override 
    public boolean isMutable() { 
     return false; 
    } 

    @Override 
    public Object replace(final Object original, final Object target, final Object owner) throws HibernateException { 
     return original; 
    } 

    @Override 
    public Class<double[]> returnedClass() { 
     return double[].class; 
    } 

    @Override 
    public int[] sqlTypes() { 
     return new int[] { SQLTYPE }; 
    } 
} 

При попытке сохранить объект, содержащий двойные [], то CCODE терпит неудачу со следующим исключением

java.lang.AbstractMethodError: com.mchange.v2.c3p0.impl.NewProxyConnection.createArrayOf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/sql/Array; 

    at com.mycompany.DoubleArrayUserType.nullSafeSet(DoubleArrayUserType.java:30) 
    at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:141) 
    at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2598) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2883) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3386) 
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560) 
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465) 
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963) 
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339) 
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231) 
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65) 
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61) 
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) 
    at com.sun.proxy.$Proxy141.save(Unknown Source) 

, который берет начало в строке Array array = connection.createArrayOf("DOUBLE", doubles); моего DoubleArrayUserType класса.
Похоже, что строка val "DOUBLE" неуместна, но я не могу понять, почему. У кого-нибудь есть идеи?

+0

Я думаю, проблема в том, что класс, который вы вызываете (com.mchange.v2.c3p0.NewProxyConnection), был скомпилирован против более раннего определения интерфейса, то есть со старым JDK. – Michal

+0

Я включил c3p0 с Maven и попробовал самую новую версию (0.9.5.2). Как такая ошибка может быть возможна? Любые идеи, как я мог это исправить? – Tobson

+0

Я клонировал последний мастер c3p0, есть стадия README, которая поддерживает файлы JDBC 3.0 и build.properties, определяющие jvm.target.version = 1.6. JDBC от JDK 1.7 не совместим в обратном направлении. http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#incompatabilities – Michal

ответ

1

Похоже, что используемый пул соединений c3p0 не поддерживает JDBC 4.1.

Вам нужно использовать другой пул соединений или получить c3p0, скомпилированный на 1.7+ JDK.

+0

Итак, в основном вы говорите, что я не должен/не могу использовать c3p0 вообще с требованиями, которые у меня есть, пока они не поддержка JDBC 4.1? – Tobson

+0

Да, либо это, либо, возможно, попытайтесь скомпилировать c3p0 с 1.7+ JDK и 1.7+. Тем не менее, возможно, что источникам нужно какое-то возиться, я понятия не имею, сколько. Я бы пошел на другой пул соединений. – Michal