Unexpected getResultStream() behavior - onClose not called


I am using getResultStream() and just found what I think is an unexpected behavior.

Using Hibernate 5.4.18.Final;

This code should print “closed”, but it doesn’t.

var query = em.createNativeQuery("select 1");
Stream<Object> stream = query.getResultStream();
stream = stream.onClose(() -> System.out.println("closed"));
// nothing printed

We can check this using a regular java stream:

var stream = Arrays.asList(new int[] {}).stream();
stream = stream.onClose(() -> System.out.println("closed"));
// prints closed

I think the problem is related to the class StreamDecorator.
It seems this class tries to deal with closeHandlers, but I don’t think this class is needed at all.
Acording to Stream specs, we can add many closeHandlers to a stream, and they will be all executed in the order they were added.
It seems the developer misunderstood that, thinking there would be just one closeHandler for a stream, and he tried to deal with the possibility of someone add another closeHandler.
As you can see, we can register many closeHandlers, so it seems the standard Java implementation can handle this.

var stream = Arrays.asList(new int[] {}).stream();
stream = stream.onClose(() -> System.out.println("closed 1"));
stream = stream.onClose(() -> System.out.println("closed 2"));
// prints closed 1
// prints closed 2

Looking at AbstractProducedQuery.stream() method, which calls StreamDecorator:

		final Stream<R> stream = new StreamDecorator(
				StreamSupport.stream( spliterator, false ),
		return stream;

It seems this would be enough (didn’t check).

return StreamSupport.stream( spliterator, false ).onClose(scrollableResults::close);

Best regards,



Just tested the code and confirmed you don’t need StreamDecorator.
This class can be removed safely and we will get the expected behavior (ScrollableResultsImpl.close() will be called, and also any post appended closeHandlers).

I am new to this forum. Is this the right place to report bugs and/or to proppose code changes?


We are experiencing some issues after migrating Hibernate to version 5.4.17 (with Spring Boot update).
The connection pool get exhausted and I found this is caused by our query.stream.onClose(session::close) not being called.
After some investigation, I came to the exact same conclusion as you: the problem seems to be in the StreamDecorator:

	public Stream<R> onClose(Runnable closeHandler) {
		this.closeHandler = closeHandler;
		return this;

The closeHandler is replaced by the new one, while in AbstractPipeline:

sourceStage.sourceCloseAction =
                (existingHandler == null)
                ? closeHandler
                : Streams.composeWithExceptions(existingHandler, closeHandler);

There’s indeed a handler composition mecanism.

Did you manage to get any attention on this issue ? Or did you submit a PR ?


1 Like

We are having the same issue as you, has anyone been able to get some help from the hibernate team?