3

ich mit Spring-Boot und versuchen, eine findAll Abfrage in mu-Repository zu tun, die einen Strom von Ergebnissen zurückgeben sollte:Frühling JpaRepository findAll, Java 8 Strom, Verbindung aufgegeben wurde

public interface MyThingRepository extends JpaRepository<MyThing, String> { 
    Stream<MyThing> findAll(); 
} 

public class MyScheduledJobRunner { 

    @Autowired 
    private MyThingRepository myThingRepository; 

    public void run() { 
     try (Stream<MyThing> myThingsStream : myThingRepository.findAll()) { 
     myThingsStream.forEach(myThing -> { 
      // do some stuff 
     }); 
     // myThingsStream.close(); // <- at one point even tried that, though the stream is wrapped in an auto-closing block. anyway, it did not help 
     System.out.println("All my things processed."); 
    } 
    System.out.println("Exited the auto-closing block."); 
    } 
} 

Ausgabe, die ich bekommen ist:

All my things processed. 
Exited the auto-closing block. 
o.a.tomcat.jdbc.pool.ConnectionPool  : Connection has been abandoned PooledConnection[[email protected]]:java.lang.Exception 
| at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1061) 
... 
at MyScheduledJobRunner.run(MyScheduledJobRunner:52) 

MyScheduledJobRunner: 52:

try (Stream<MyThing> myThingsStream : myThingRepository.findAll()) { 

per Dokumentation, wenn St mit In JpaRepositories sollten Sie diese nach der Verwendung immer wieder schließen. Da sie AutoCloseable implementieren, können Sie try with resources block verwenden. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-streaming

Ein Stream-Wraps potenziell zugrunde liegenden Datenspeicher spezifische Ressourcen und damit nach Gebrauch geschlossen werden müssen. Sie können den Stream entweder manuell mithilfe der close() -Methode oder mithilfe eines Java 7-Try-with-resources-Blocks schließen.

Es gibt sogar ein Beispiel in der Dokumentation, die es genau so macht, wie ich es tue. Also mache ich die ganze Dokumentation, sagt, soweit ich das beurteilen kann, aber trotzdem bekomme ich 30 Sekunden nach der Operation eine Ausnahme. Offensichtlich ist die Verbindung also nicht geschlossen und bleibt hängen. Warum ist das und wie könnte ich das überwinden?

Ich habe mit Postgres 9.5 und MariaDB als Datenbank versucht. Ich verwende die neuesten möglichen Anschlüsse/Treiber und Tomcat Connection Pooling, die durch Federstiefel Eigenschaften wie das konfiguriert ist:

spring: 
    datasource: 
    driverClassName: com.mysql.jdbc.Driver 
    url: jdbc:mysql://localhost/mydb?useSSL=false 
    username: user 
    password: password 
    initial-size: 10 
    max-active: 100 
    max-idle: 50 
    min-idle: 10 
    max-wait: 15000 
    test-while-idle: true 
    test-on-borrow: true 
    validation-query: SELECT 1 
    validation-query-timeout: 5 
    validationInterval: 30000 
    time-between-eviction-runs-millis: 30000 
    min-evictable-idle-time-millis: 60000 
    removeAbandonedTimeout: 60 
    remove-abandoned: true 
    log-abandoned: true 
+0

Ich bin mir sicher, dass es List und Page zurückgibt. Ich bin mir nicht sicher, ob es wieder Strom gibt. Was auch immer. Haben Sie Anmerkungen geschrieben wie: @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME), @Service und haben Sie Creators (@Configuration) für DataSource Beans, Repository Beans, ServiceBeans? – LowLevel

+0

Ja. Alle meine Anmerkungen und Bohnen sind eingestellt. Wenn sie nicht gesetzt wären, würde mein Datenbank-Zeug überhaupt nicht funktionieren, aber es funktioniert gut. Nur dieser scheußliche abgebrochene Verbindungsfehler, den ich in meinen Logs nicht mag. Dies ist nur ein minimales Beispiel. Und wenn Sie sich den von mir bereitgestellten Dokumentationslink ansehen, werden Sie sehen, dass Spring Boot JPA mit Java 8 zusätzlich zu Page und Collection auch Stream unterstützt. Die Motivation, warum ich Stream statt einer Page oder Collection verwende, ist, dass die Menge von MyThings potentiell humong ist und ich sie nicht im Speicher lesen kann. – Tarmo

+0

Und wenn Sie versuchen, eine Liste zu bekommen, bekommen Sie es? – LowLevel

Antwort

0

in Pool-Konfiguration nur u hinzufügen müssen: „org.apache.tomcat.jdbc.pool .interceptor.ResetAbandonedTimer "

+2

Bitte erläutern warum und wie diese Eigenschaft würde mir helfen? – Tarmo

+0

finden Sie die Informationen in diesem Link: http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency ,,,, diese Eigenschaft Timeout zurücksetzen – kuciB

+0

Es klingt Aus, dass, um Spring-Funktionalität aus der Box zu nutzen, die gut dokumentiert ist, um keine Ausnahmen zu bekommen, muss ich einige zufällige Tomcat-Parameter einstellen. Am besten ist in diesem Fall ein Dokumentationsfehler IMO. Wie auch immer, ich konnte das nicht zur Arbeit bringen (ClassNotFound) – Tarmo