10 Kasım 2022 Perşembe

JDBC BatchUpdateException

Giriş
Şu satırı dahil ederiz
import java.sql.BatchUpdateException;
Açıklaması şöyle
BatchUpdateException: This type of exception will be thrown if any error has occurred while doing the batch update operation. Besides the SQLException information, BatchUpdateException provides the status of the statements which have been executed/updated before the error has occurred.
Kullanım Örneği
Yani kod şöyledir. addBatch() çağrısı yapılmaktadır
try(Connection conn = ...;
    Statement statement = conn.createStatement()) {
//Adding the 3 insert queries into the Statement object using addBatch method statement.addBatch(insert_query1);
statement.addBatch(insert_query2);
statement.addBatch(insert_query3);
int afffectedRows[] = statement.executeBatch();
} catch(BatchUpdateException exception) { ... }
Çeşitli Sürücüler İçin Notlar
1. MySQL Sürücüsü
BatchUpdateException içinde SQLIntegrityConstraintViolationException var ve SQLState "23000"

Örnek
Hata şöyle olabilir. Bath insert işleminde bir satır zaten mevcut.
java.sql.BatchUpdateException: Duplicate entry '0' for key 'foo.PRIMARY'

2. PostgreSQL Sürücüsü
BatchUpdateException içinde org.postgresql.util.PSQLException var ve SQLState "23505"

Örnek
Hata şöyle olabilir. Bath insert işleminde bir satır zaten mevcut.
java.sql.BatchUpdateException: Batch entry 0 INSERT INTO foo ( "id","name" )  VALUES (0, 'updated') was aborted: ERROR: duplicate key value violates unique constraint "..."
  Detail: Key (id)=(0) already exists.  Call getNextException to see other errors in the batch.

3. H2
org.h2.jdbc.JdbcBatchUpdateException zaten java.sql.BatchUpdateException sınıfından kalıtıyor
SQLState "23505"
Örnek
Hata şöyle olabilir. Bath insert işleminde bir satır zaten mevcut.
org.h2.jdbc.JdbcBatchUpdateException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.foo(id) ( /* key:0 */ 0, 'name-0')"; SQL statement:
INSERT INTO foo ( "id","name" )  VALUES (?, ?) [23505-214]

Eğer bunları bir string şeklinde isteseydik şöyle olurdu
String H2_PK_VIOLATION = "Unique index or primary key violation";
String PG_PK_VIOLATION = "ERROR: duplicate key value violates unique constraint";
String MYSQL_PK_VIOLATION = "Duplicate entry";
Integrity Violation Kontrolü
İki yöntem var. Burada gördüm

1. Spring gibi vendor kodlarını XML içinde toplamak
2. Kodla SQLState değerine bakmak. 23XX şeklinde olmalı

Örnek
Şöyle yaparız
Throwable findSQLException(Throwable throwable) {
  Throwable rootCause = throwable;
  while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
    rootCause = rootCause.getCause();
    if (rootCause instanceof SQLException) {
      return rootCause;
    }
  }
  return null;
}

// SQLException returns SQL state in five digit number.
// These five-digit numbers tell about the status of the SQL statements.
// The SQLSTATE values consists of two fields.
// The class, which is the first two characters of the string, and
// the subclass, which is the terminating three characters of the string.
// See https://en.wikipedia.org/wiki/SQLSTATE for cate
boolean isIntegrityConstraintViolation (Exception exception) {
  boolean result = false;
  Throwable rootSQLException = findSQLException(exception);
  if (rootSQLException != null) {
    SQLException sqlException = (SQLException) rootSQLException;
    String sqlState = sqlException.getSQLState();
    if (sqlState != null) {
      result = sqlState.startsWith("23");
    }
  }
  return result;
}
getUpdateCounts() metodu
İmzası şöyle
int[] getUpdateCounts()
Açıklaması şöyle
How to find which statement failed in a JDBC Batch Update?
However, we can pinpoint the failing statements by introspecting the result of the getUpdateCounts method on the java.sql.BatchUpdateException that is thrown by the JDBC Driver.

Because the getUpdateCounts method returns an int[] array with two entries, we know that only two statements were successfully processed. So, the third statement was the one causing the failure.



Hiç yorum yok:

Yorum Gönder