ignite icon indicating copy to clipboard operation
ignite copied to clipboard

Occasional error reporting :Failed to register class

Open sdjakhfjkdsafn opened this issue 2 years ago • 3 comments

An error is occasionally reported when the insert statement is executed in stream mode. The error stack indicates org.apache.ignite.internal.jdbc.thin.JdbcThinConnection:1545 | Exception during batch send on streamed connection close java.sql.BatchUpdateException: Failed to register class. at org.apache.ignite.internal.jdbc.thin.JdbcThinConnection$StreamState.readResponses(JdbcThinConnection . java: 1567) at java.Lang.Thread.run(Thread.java:748)

sdjakhfjkdsafn avatar Jan 27 '24 03:01 sdjakhfjkdsafn

@sdjakhfjkdsafn , hi! Can you attach full stack trace of the error?

shishkovilja avatar Mar 21 '24 18:03 shishkovilja

I only have this, because it is wrapped externally. My code throws an error when starting stream mode, and with the same data, running it again makes it work normally. The logic of my code is similar to the following. public int insertData(Connection conn, ResultSet resSet, EnhanceInsertModelForSingleSql insertModel) throws SQLException{ int rowCount = 0; Statement stmt = null; try { stmt = conn.createStatement(); stmt.setQueryTimeout(7200); stmt.execute(SET STREAMING ON;); PreparedStatement preparedStatement = conn.prepareStatement(insertModel.getPrepareStament()); try { while (resSet.next()) { rowCount++; int columnIndex = 1; for (ColumnDefinition column : insertModel.getColumnsForInsert()) { Object value = null; switch (column.getType()) { case UUID: value = UUID.randomUUID().toString(); break; case DEFAULT: value = getColumnValue(resultSet, column); break; default: LOGGER.warn("Column {} can't set value with type {}", column.getName(), column.getType()); continue; } setValue(preparedStatement, columnIndex, column, value); columnIndex++; } preparedStatement.addBatch(); if (rowCount % targetSource.getBatchExecuteNum() == 0) { log.debug("execute batch rowCount:{}", rowCount); checkInterrupted(); executeBatchWithTimeout(rowCount, preparedStatement); } } preparedStatement.executeBatch(); return rowCount; } catch (BatchUpdateException batchUpdateException) { LOGGER.error("execute Batch error. " + batchUpdateException.getMessage()); rowCount = 0; preparedStatement.clearBatch(); resSet.close(); stmt.execute(SET_IGNITE_STREAMING_OFF); LOGGER.info("drop table {}. " + tableDefinition.getName()); dropTableByName(conn, tableDefinition.getName()); LOGGER.info("drop table {} complete.", tableDefinition.getName()); if (isAllowRetry() || batchUpdateException.getMessage().contains("Failed to register class")) { rowCount = insertRetry(conn, preparedStatement, insertModel, rowCount, stmt); return rowCount; } log.error("execute batch error stack is ", batchUpdateException); throw new Roma3cSqlException("execute Batch error. " + batchUpdateException.getMessage()); } finally { preparedStatement.close(); } } finally { resSet.close(); resSet.getStatement().close(); resSet.getStatement().getConnection().close(); if (stmt != null) { boolean isClosed = false; try { stmt.execute(SET_IGNITE_STREAMING_OFF); isClosed = true; } finally { if (!isClosed) { stmt.execute(SET STREAMING ON;); stmt.execute(SET STREAMING OFF;); } stmt.close(); } } } } The error is thrown when catching a BatchUpdateException.and reports Failed to register class

sdjakhfjkdsafn avatar Mar 22 '24 01:03 sdjakhfjkdsafn

@sdjakhfjkdsafn , hi! Can you attach full stack trace of the error? I only have this, because it is wrapped externally. My code throws an error when starting stream mode, and with the same data, running it again makes it work normally. The logic of my code is similar to the following. public int insertData(Connection conn, ResultSet resSet, EnhanceInsertModelForSingleSql insertModel) throws SQLException{ int rowCount = 0; Statement stmt = null; try { stmt = conn.createStatement(); stmt.setQueryTimeout(7200); stmt.execute(SET STREAMING ON;); PreparedStatement preparedStatement = conn.prepareStatement(insertModel.getPrepareStament()); try { while (resSet.next()) { rowCount++; int columnIndex = 1; for (ColumnDefinition column : insertModel.getColumnsForInsert()) { Object value = null; switch (column.getType()) { case UUID: value = UUID.randomUUID().toString(); break; case DEFAULT: value = getColumnValue(resultSet, column); break; default: LOGGER.warn("Column {} can't set value with type {}", column.getName(), column.getType()); continue; } setValue(preparedStatement, columnIndex, column, value); columnIndex++; } preparedStatement.addBatch(); if (rowCount % targetSource.getBatchExecuteNum() == 0) { log.debug("execute batch rowCount:{}", rowCount); checkInterrupted(); executeBatchWithTimeout(rowCount, preparedStatement); } } preparedStatement.executeBatch(); return rowCount; } catch (BatchUpdateException batchUpdateException) { LOGGER.error("execute Batch error. " + batchUpdateException.getMessage()); rowCount = 0; preparedStatement.clearBatch(); resSet.close(); stmt.execute(SET_IGNITE_STREAMING_OFF); LOGGER.info("drop table {}. " + tableDefinition.getName()); dropTableByName(conn, tableDefinition.getName()); LOGGER.info("drop table {} complete.", tableDefinition.getName()); if (isAllowRetry() || batchUpdateException.getMessage().contains("Failed to register class")) { rowCount = insertRetry(conn, preparedStatement, insertModel, rowCount, stmt); return rowCount; } log.error("execute batch error stack is ", batchUpdateException); throw new Roma3cSqlException("execute Batch error. " + batchUpdateException.getMessage()); } finally { preparedStatement.close(); } } finally { resSet.close(); resSet.getStatement().close(); resSet.getStatement().getConnection().close(); if (stmt != null) { boolean isClosed = false; try { stmt.execute(SET_IGNITE_STREAMING_OFF); isClosed = true; } finally { if (!isClosed) { stmt.execute(SET STREAMING ON;); stmt.execute(SET STREAMING OFF;); } stmt.close(); } } } } The error is thrown when catching a BatchUpdateException.and reports Failed to register class

sdjakhfjkdsafn avatar Mar 22 '24 01:03 sdjakhfjkdsafn