java / intermediate
Snippet
Vermeidung von Out-of-Memory-Fehlern durch JPA-Abfrageergebnis-Streaming
Das Laden großer Datenmengen als einzelne `List<T>` lädt alle Datensätze gleichzeitig in den JVM-Heap und riskiert einen `OutOfMemoryError`. Die Rückgabe eines Java-8-`Stream<T>` in Kombination mit `@Transactional(readOnly = true)` ermöglicht das schrittweise Streamen von Zeilen über den Datenbank-Cursor, wodurch der Heap-Verbrauch bei der Verarbeitung großer Ergebnismengen konstant bleibt.
snippet.java
java
1
2
3
4
5
6
7
8
9
10
@Servicepublic class ExportService {@Transactional(readOnly = true)public void exportAuditLogs(Consumer<AuditLog> consumer) {try (Stream<AuditLog> logStream = auditLogRepository.streamAllByStatus(Status.PENDING)) {logStream.forEach(consumer);}}}
spring
Erklärung
1
@Transactional(readOnly = true)
Hält die Datenbankverbindung und den Resultset-Cursor während der Stream-Iteration geöffnet.
2
try (Stream<AuditLog> logStream = auditLogRepository.streamAllByStatus(Status.PENDING)) {
Öffnet einen Try-with-Resources-Block, um das Schließen des Datenbank-Cursors nach Abschluss des Streamings sicherzustellen.
3
logStream.forEach(consumer);
Verarbeitet Entitäten sequenziell beim Eintreffen vom Cursor, ohne alle Einträge im Speicher zu puffern.