1

最近、hibernate 3.5 から 4.1.7 に、spring を 3.0.5 から 3.1.3 にアップグレードしました。Hibernate は春に jpa を介して設定されるため、変更は行われません。

アップグレード後、ほとんどのものは正常に動作しますが、ストアド プロシージャを使用する関数の 1 つが次の例外を除いて壊れています。

java.lang.ClassCastException: $Proxy188 は oracle.jdbc.OracleConnection にキャストできません
oracle.sql.TypeDescriptor.setPhysicalConnectionOf(TypeDescriptor.java:829) で oracle.sql.TypeDescriptor.(TypeDescriptor.java:583) で oracle.sql.ArrayDescriptor.(ArrayDescriptor.java:224) で org.springframework.data. org.springframework.jdbc.core.support.AbstractSqlTypeValue.setTypeValue(AbstractSqlTypeValue.java:58) の jdbc.support.oracle.SqlArrayValue.createTypeValue(SqlArrayValue.java:71) org.springframework.jdbc.core.StatementCreatorUtils.setValue( StatementCreatorUtils.java:281) org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:217) org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:128) org.springframework.jdbc 。芯。CallableStatementCreatorFactory$CallableStatementCeatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:212) で org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1008) で org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1064) org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144) で

デバッグ モードでは、AbsructSqlTypeValue.setTypeValue()メソッドに次の実装があることがわかりました。

public final void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName)
        throws SQLException {

    Object value = createTypeValue(ps.getConnection(), sqlType, typeName);
    if (sqlType == TYPE_UNKNOWN) {
        ps.setObject(paramIndex, value);
    }
    else {
        ps.setObject(paramIndex, value, sqlType);
    }
}

ここでのps.getConnection()メソッドは実際には、実際の OracleConnection をラップする新しい Hibernate 4 LogicalConnectionImpl を返します。そのため、Oracle ドライバーで ClassCastException がスローされます。

oracle.SqlArrayValue を呼び出す理由は、ストアド プロシージャが long のリストを入力パラメータとして受け取るためです。入力パラメーターが定義されるとOracleTypes.ARRAY、値をバインドするときに使用し、新しいSqlArrayValueオブジェクトを作成して をラップしますLong[]Types.Arrayジェネリックを直接使用しようとしましたLong[]が、次の例外があり、どちらも機能しませんでした:

原因: java.sql.SQLException: 内部表現への変換に失敗しました: [Ljava.lang.Long;@337f5afe
oracle.sql.ARRAY.toARRAY(ARRAY.java:187) で oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8782) で oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8278) でoracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8877) at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:4992) at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:240) sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブ メソッド) で sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) で sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597)で oracle.ucp.jdbc.proxy.StatementProxyFactory.invoke(StatementProxyFactory.java:230)で oracle.ucp.jdbc.proxy.PreparedStatementProxyFactory.invokeで(PreparedStatementProxyFactory.java:124) at oracle.ucp.jdbc.proxy.CallableStatementProxyFactory.invoke(CallableStatementProxyFactory.java:101) at $Proxy214.setObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun. org.hibernate.engine で java.lang.reflect.Method.invoke(Method.java:597) で sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) で.jdbc.internal.proxy.AbstractStatementProxyHandler。continueInvocation(AbstractStatementProxyHandler.java:122)

jdbcTemplate がネイティブの代わりに休止状態接続を使用する理由がわかりませんOracleConnection。おそらく、魔法のように修正できる設定がどこかにあるのでしょうか。

4

1 に答える 1

0

Found the root cause of it. The class that extends StoredProcedure didn't define the jdbcTemplate property so the default one is used which doesn't have nativeJdbcExtractor defined. After adding the jdbcTemplate dependency to refer to the one defined with org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor as nativeJdbcExtractor resolve the issue. I guess hibernate 3.5 with spring 3.0 doesn't have this issue since at that time the returned jdbc connection is already the OracleConnection.

于 2012-11-08T06:10:31.360 に答える