Speichern eines zurückgesetzten Datensatzes, der mit JPA und Ruhezustand einen Batchfehler verursacht hat

Verwenden Sie diese in diesem Artikel beschriebene Technik, um herauszufinden, welcher Datensatz das Problem verursacht.

Sie können nur die Anzahl der Datensätze in einem Stapel reduzieren, für den Sie die Transaktion festschreiben, und einen neuen Datensatz starten. Mit der folgenden Technik können Sie weniger Einträge haben, die sofort zurückgesetzt werden.

int entityCount = 100;
int batchSize = 5;

EntityManager entityManager = null;
EntityTransaction-Transaktion = null;

Versuchen {
entityManager = entityManagerFactory (). createEntityManager ();

transaction = entityManager.getTransaction ();
transaction.begin ();

für (int i = 0; i <entityCount; ++ i) {
if (i> 0 && i% batchSize == 0) {
entityManager.flush ();
entityManager.clear ();

transaction.commit ();
transaction.begin ();
}

Post post = neuer Post (String.format (“Post% d”, i));
entityManager.persist (post);
}

transaction.commit ();
} catch (RuntimeException e) {
if (transaction! = null && transaction.isActive ()) {
transaction.rollback ();
}
wirf e;
} schließlich {
if (entityManager! = null) {
entityManager.close ();
}
}

Auf diese Weise minimieren Sie die Anzahl der Datensätze, die aufgrund eines Fehlers zurückgesetzt werden, und wiederholen die Datensätze, die den Fehler nicht verursacht haben. Der Konus, der den Fehler verursacht, muss separat gespeichert werden, möglicherweise in einer JSON-Spalte, da dies möglicherweise eine Spaltenbeschränkung war, die das Problem verursacht hat. Später können Sie die Ursache ermitteln, beheben und erneut versuchen.

Sie müssen die Ausnahme für jeden Datensatz behandeln, den Sie speichern. Auf diese Weise können Sie das Rollback für den gesamten Stapel verhindern. Das kann so gemacht werden:

Schleife über 100 Datensätze {
Versuchen {
session.save (Entität)
}
catch (Ausnahme e) {
Ausnahme protokollieren oder Liste der fehlgeschlagenen Datensätze erstellen, die später verarbeitet werden sollen.
}
} // Ende der Schleife
session.flush ()

Oder behalten Sie die Methode zum Speichern der Stapel in einer neuen Transaktion bei, um die explizite Verwendung von flush () zu vermeiden. Am Ende der Transaktion wird die Sitzung geleert, um die durchgeführten Datenbankoperationen zu synchronisieren.