2016-02-22 21 views
6

Ich habe eine JOOQ-Abfrage, wo ich vermeiden möchte, alle Datensätze zur gleichen Zeit zu materialisieren. (Aber ich bin gut mit gemeinsam alle Bean-Objekten von ihnen erstellt materialisieren.)Kann ich ein JDBC-Verbindungsleck riskieren, wenn JOOQ-Ergebnisse außerhalb eines Try-with-Resources-Blocks gestreamt werden?

Ich habe die folgende einfache Methode, um die Daten zu laden:

public List<CustomerInfo> getCustomers() { 
    return dslContext 
       .selectFrom(CUSTOMER) 
       // <-- note the missing .fetch() 
       .stream() 
       .map(CustomerInfo::new) 
       .collect(Collectors.toList()); 
} 

Kann diese führen zu einem JDBC-Verbindung Leck unter allen Umständen ? (ZB eine Ausnahme in CustomerInfo::new)

Antwort

4

Ich habe mein Glück versucht, einen Weg zu finden, einen zuverlässigen Strom „Fertigstellung“ Haken zu registrieren, die auf vollständigen Strom Verbrauch oder auf jede Ausnahme ausgelöst wird, aber das ist leider nicht möglich: Register a Stream "completion" hook

In der Tat ist der Code, den Sie gezeigt haben, nicht korrekt. Der richtige Weg, um mit "Lazy" -Streams (oder Cursor) zu arbeiten, ist die try-with-resources-Anweisung. Die folgenden zwei äquivalent:

// Using a Stream 
try (Stream<CustomerRecord> stream = dslContext.selectFrom(CUSTOMER).stream()) { 
    return stream.map(CustomerInfo::new).collect(Collectors.toList()); 
} 

// Using a Cursor 
try (Cursor<CustomerRecord> cursor = dslContext.selectFrom(CUSTOMER).fetchLazy()) { 
    return cursor.stream().map(CustomerInfo::new).collect(Collectors.toList()); 
} 

Beachten Sie auch den ResultQuery.stream() Javadoc-:

Dies ist im Wesentlichen die gleiche wie fetchLazy(), sondern stattdessen einen Cursor zurückzukehren, ein Java-Strom 8 zurückgeführt wird. Clients sollten sicherstellen, dass der Stream ordnungsgemäß geschlossen ist, z. in einer Try-with-Resources-Anweisung