JDBC PreparedStatement, пакетное обновление и сгенерированные ключи - PullRequest
6 голосов
/ 30 января 2012

У меня проблема с использованием jdbc prepareStatement в пакете и попыткой получить сгенерированные ключи, созданные из этого.

код:

        PreparedStatement stmt = null;
    ...
    connection.setAutoCommit(false);
    stmt = connection.prepareStatement(insertSuspiciousElement,new String[] {"external_id","element_id"});
final int elementBatchSize = 5000;
    int elementCount =0;
        for(BlSuspiciousElement element : elements){
        externalIds.add(element.getExternalId());
        stmt.setInt(1, element.getBlElementType().getElementTypeId());
        stmt.setString(2, element.getFirstname());
        stmt.addBatch();
        elementCount++;
        if(elementCount % elementBatchSize == 0){
            System.out.println("Running query with batch size for suspiciousElement");
            stmt.executeBatch();

            ResultSet keys = stmt.getGeneratedKeys();
            while(keys.next()){
                externalIdElementIdMapping.put(keys.getInt("external_id"),keys.getInt("element_id"));
            }
            keys.close();
            stmt.clearBatch();
            stmt.clearParameters();
            stmt.clearWarnings();
            System.out.println("Done query with batch size for suspiciousElement");
        }
        }

происходит сбой при первом методе stmt.executeBatch ().

Ошибка:

[30/01/12 15:54:41:684 CET] 00000029 RemoteExcepti E   CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "processFullFeedForPepAndRelationUpdateOnly" on bean "BeanId(CoRelateEar#AmlKycToolBO.jar#FactivaDBUpdater, null)". Exception data: java.lang.ArrayIndexOutOfBoundsException
at oracle.jdbc.driver.T4CNumberAccessor.unmarshalOneRow(T4CNumberAccessor.java:201)
at oracle.jdbc.driver.T4C8Oall.readRXD(T4C8Oall.java:696)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:340)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
at oracle.jdbc.driver.OraclePreparedStatement.executeForRowsWithTimeout(OraclePreparedStatement.java:10143)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10249)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at com.ibm.ws.rsadapter.jdbc.WSJdbcStatement.executeBatch(WSJdbcStatement.java:748)

Не очень очевидно для меня ...

Кажется, что он не работает для пакетных обновлений? Только для заявления или подготовленного заявления. В этом случае, я думаю, мне лучше попробовать выполнить пакетную вставку, а затем выполнить другой запрос, чтобы найти сгенерированные ключи для каждого созданного элемента ...

Спасибо за вашу помощь,

F

1 Ответ

0 голосов
/ 30 января 2012

Полагаю, вы должны сообщить драйверу Oracle JDBC, что вы будете получать сгенерированные ключи.

Ознакомьтесь с принятым ответом на следующий вопрос для получения подробной информации: PreparedStatement с Statement.RETURN_GENERATED_KEYS .

РЕДАКТИРОВАТЬ 1/31/12: Если этот подход не работает с пакетным режимом (а я не пробовал его с пакетным режимом), вы можете вместо пакетного режима просто отключить автокоммит, сделать вставки для всех ваших данных и затем совершить. В моих экспериментах снижение производительности для этого подхода составило всего 3%. Я также нашел другую аналогичную рекомендацию для SO: MySQL пакетного stmt с Statement.RETURN_GENERATED_KEYS .

...