2016-12-07 8 views
4

J'ai un dépôt Spring data:méthode de dépôt de printemps qui reviennent flux Java 8 ne ferme pas la connexion JDBC

@Repository 
interface SomeRepository extends CrudRepository<Entity, Long> { 
    Stream<Entity> streamBySmth(String userId); 
} 

J'appelle cette méthode dans une fève de printemps:

@Scheduled(fixedRate = 10000) 
private void someMethod(){ 
    someRepository.streamBySmth("smth").forEach(this::callSomeMethod); 
} 

Je suis en utilisant la base de données MySQL. Et quand je demande en cours d'exécution après quelques invocations de méthode avec succès, il lance une exception:

o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 08001 
o.h.engine.jdbc.spi.SqlExceptionHelper : Could not create connection to database server. 
o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task. 

org.springframework.dao.DataAccessResourceFailureException: Unable to acquire JDBC Connection; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection 

Il semble que la connexion n'a pas été fermée correctement au printemps. Si j'ai changé la valeur de retour de méthode à List de Stream cela fonctionne correctement.

MISE À JOUR: la version Spring Boot est 1.4.1.RELEASE

+2

Avez-vous essayé d'appeler 'close' sur le flux? – marstran

+0

J'ai essayé, ça n'a pas aidé. Néanmoins, il n'est pas correct de fermer manuellement 'Stream'. –

+0

Je ne suis pas très familier avec le retour d'un 'Stream' d'un dépôt, mais un' Stream' est paresseux, alors comment Spring sait-il quand fermer la connexion? 'Stream' est aussi' AutoClosable', donc vous pouvez l'utiliser dans une clause try-with-resources. – marstran

Répondre

7

Comme le reference documentation clearly states, Stream s doivent être utilisés avec un essai avec-ressources bloc.

De même, assurez-vous de garder une transaction (en lecture seule) ouverte pendant le temps de consommation du flux en annotant la méthode environnante avec @Transactional. Sinon, les paramètres par défaut s'appliquent et les ressources sont tentées d'être libérées lors du retour de la méthode du référentiel.

@Transactional 
public void someMethod() { 

    try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) { 
    stream.forEach(…); 
    } 
} 
+0

Il semble raisonnable mais il ne nous aide pas. J'ai toujours la même erreur après plusieurs demandes. –

+0

Malheureusement, cela n'aide plus. J'ai essayé d'utiliser '@Transactional (readOnly = true)' et j'ai aussi essayé de '.close()' streams. Maintenant, il fonctionne avec succès 100 comptes et échoue. Si je comprends bien, cela signifie que de nouvelles connexions sont ouvertes à chaque demande. Peut-il être un bug de printemps? –

+0

Pouvez-vous fournir un échantillon reproduisant votre problème? Il y a un ticket avec un problème décrit qui semble lié [ici] (https://jira.spring.io/browse/DATAJPA-917) mais qui peut être résolu en suivant ce que j'ai décrit ci-dessus. –