Я использую Spring бутс и пытаюсь сделать запрос FindAll в мю хранилища, которое должно возвращать поток результатов:Spring JpaRepository FindAll, Java 8 потока, соединение было оставлено
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.");
}
}
Вывода, который я получаю это:
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()) {
согласно документации, при использовании St в JpaRepositories вы должны всегда закрывать их после использования. Поскольку они реализуют AutoCloseable, вы можете использовать try с блоком ресурсов. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-streaming
поток потенциально обертывание, лежащие в основе хранилища данных конкретных ресурсов и, следовательно, должны быть закрыт после использования. Вы можете вручную закрыть Stream с помощью метода close() или с помощью блока try-with-resources Java 7.
В документации есть пример, который делает это точно так же, как и я. Поэтому я делаю всю эту документацию, насколько я могу судить, но все же я получаю исключение через 30 секунд после операции. По-видимому, связь не закрыта и остается висящей. Почему это и как я могу это преодолеть?
Я пробовал с Postgres 9.5 и MariaDB в качестве базы данных. Я использую новейшие возможные разъемы/драйвера и Tomcat пулы соединений, которые настроены через свойство рессоры ботинка так:
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
Я уверен, что он возвращает список и страницу. Я не уверен, вернет ли он поток. Без разницы. Вы пишете аннотации, такие как: @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME), @Service и у вас есть создатели (@Configuration) для компонентов DataSource, репозитория Beans, ServiceBeans? – LowLevel
Да. Все мои аннотации и бобы установлены. Если они не будут установлены, то материал базы данных не будет работать вообще, но он работает хорошо. Просто эта неприятная ошибка отказавшего соединения, которая мне не нравится в моих журналах. Это всего лишь минимальный пример. И если вы посмотрите на ссылку для документации, которую я предоставил, вы увидите, что Spring Boot JPA с Java 8 поддерживает Stream в дополнение к странице и коллекции. Мотивация, почему я использую Stream вместо страницы или коллекции, состоит в том, что набор MyThings потенциально опасен, и я не могу прочитать его в памяти. – Tarmo
И если вы попытаетесь получить Список, вы его получите? –
LowLevel