2012-01-30 15 views
5

Ho un problema con jdbc preparedStatement in batch e sto cercando di ottenere le chiavi generate create da questo.JDBC PreparedStatement, Batch Update e chiavi generate

Il codice:

 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"); 
     } 
     } 

fallisce al primo metodo stmt.executeBatch().

L'errore:

[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) 

Non molto evidente per me ...

Sembra che non funziona per gli aggiornamenti batch? Solo per dichiarazioni o dichiarazioni preparate. In questo caso, penso che farei meglio cerco di fare il mio inserto in batch, e quindi eseguire un'altra query per trovare le chiavi generate per ogni elemento creato ...

Grazie per il vostro aiuto,

F

risposta

0

Credo che dovresti dire al driver Oracle JDBC che avresti recuperato le chiavi generate.

Per i dettagli, vedere la risposta accettata alla seguente domanda: PreparedStatement with Statement.RETURN_GENERATED_KEYS.

EDIT 1/31/12: Se questo approccio non funziona con batch (e non l'ho provato con batch), è possibile invece di eseguire il batching, basta disattivare l'autocommit, fare inserimenti per tutti i dati, e poi commettere. Nei miei esperimenti la penalizzazione delle prestazioni per questo approccio era solo del 3%. Ho anche trovato un'altra raccomandazione simile su SO: MySQL batch stmt with Statement.RETURN_GENERATED_KEYS.

+0

Questo collegamento riguarda l'utilizzo solo di un documento Preparato. Il mio problema è quando sto cercando di recuperare le chiavi generate in un PreparationStatement eseguito in batch ... Leggermente diverso. – Farid

+0

@Farid: hai provato a specificare RETURN_GENERATED_KEYS durante la preparazione dell'istruzione? Qualcosa come: stmt = connection.prepareStatement (sql, Statement.RETURN_GENERATED_KEYS); – Olaf

+0

Sì, lo stesso errore. – Farid

Problemi correlati