The spring repository method that returns the Java 8 stream does not close the JDBC connection
I have a spring data repository:
@Repository interface SomeRepository extends CrudRepository<Entity,Long> { Stream<Entity> streamBySmth(String userId); }
I call this method in some Spring bean:
@Scheduled(fixedRate = 10000) private void someMethod(){ someRepository.streamBySmth("smth").forEach(this::callSomeMethod); }
I am using MySQL database When I run an application after some successful method calls, it throws an 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
It seems that spring did not close the connection properly If I have changed the return value of the method to stream from stream, it will work properly
Update: spring boot version is 1.4 1.RELEASE
Solution
As reference documentation, clearly states, streams needs to be used with the try with resources block
In addition, by using the methods around the @ transactional annotation, it is ensured that the (read-only) transaction is kept open when the flow is consumed Otherwise, the default settings are applied and an attempt is made to free the resource when the repository method returns
@Transactional public void someMethod() { try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) { stream.forEach(…); } }