Quantcast
Channel: Spring Community Forums - Data
Viewing all articles
Browse latest Browse all 297

SqlLobValue and NegativeArraySizeException with DefaultLobHandler on Oracle 10g

$
0
0
Hello!
I'm getting a NegativeArraySizeException during the invocation of a package procedure with a CLOB parameter, which is added to the stored proc calling method as a new SqlLobValue:
Code:

        public String executeNativeStoredProcedure(Reader jsonStoreDocumentMessageReader) throws PaxDataException {
                try {
                        Map<String, Object> inputs = new HashMap<String, Object>();
                        SqlLobValue sqlLobValue = new SqlLobValue(jsonStoreDocumentMessageReader, -1, lobHandler);
                        inputs.put("PL_JSON", sqlLobValue);
                        Map<String, Object> result = super.execute(inputs);
                        sqlLobValue.cleanup();
                        return result.get("OUT") != null ? result.get("OUT").toString() : null;
                } catch (Exception e) {
                        throw new PaxDataException("ArchiviaFiles - " + SPROC_NAME, e);
                }
        }

We are using Spring 3.2.2 and the database is an Oracle 10g installation (10.2).

Using the DefaultLobHandler like this:
Code:

public LobHandler dmsLobHandler() {
                DefaultLobHandler lh = new DefaultLobHandler();
                lh.setStreamAsLob(false);
                return lh;
        }

we get:
Code:

Caused by: java.lang.NegativeArraySizeException
        at oracle.jdbc.driver.OraclePreparedStatement.setReaderContentsForStringInternal(OraclePreparedStatement.java:9765)
        at oracle.jdbc.driver.OraclePreparedStatement.setCharacterStreamInternal(OraclePreparedStatement.java:9615)
        at oracle.jdbc.driver.OraclePreparedStatement.setCharacterStreamInternal(OraclePreparedStatement.java:9570)
        at oracle.jdbc.driver.OracleCallableStatement.setCharacterStream(OracleCallableStatement.java:5643)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.setCharacterStream(OraclePreparedStatementWrapper.java:656)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.setCharacterStream(DelegatingPreparedStatement.java:178)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.setCharacterStream(DelegatingPreparedStatement.java:178)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
        at org.hibernate.engine.jdbc.internal.proxy.CallableStatementProxyHandler.continueInvocation(CallableStatementProxyHandler.java:49)
        at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
        at com.sun.proxy.$Proxy131.setCharacterStream(Unknown Source)
        at org.springframework.jdbc.support.lob.DefaultLobHandler$DefaultLobCreator.setClobAsCharacterStream(DefaultLobHandler.java:348)
        at org.springframework.jdbc.core.support.SqlLobValue.setTypeValue(SqlLobValue.java:196)
        at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:281)
        at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:217)
        at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:128)
        at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:212)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1014)
        at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1070)
        at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:144)
        at axioma.web.dms.services.impl.va.stored.ArchiveFilesWithVersioning.executeNativeStoredProcedure(ArchiveFilesWithVersioning.java:58)
        ... 6 more

while using the deprecated OracleLobHandler:
Code:

public LobHandler dmsLobHandler() {
                OracleLobHandler lh = new OracleLobHandler();
                lh.setNativeJdbcExtractor(dmsJdbcExtractor());
                return lh;
        }

everything works.

I debugged the code and I think I tracked the exception rising in an invocation of setCharacterStream() (but as there are no publicly available sources for the Oracle drivers, I'm not 100% sure of that), and I managed to make it work by passing a guessed length as the second parameter of SqlLobValue() constructor.

Since the lob value is a Json string generated by other data, there's no reasonable way to know the lob size in advance (apart from doing not-so-easy precomputations or double-generating the lob to know its size, both of which I'd consider overkill).

Any suggestion?

Viewing all articles
Browse latest Browse all 297

Trending Articles