title: Stream closeable resource with Spring MVC
body: <p>After having read <a href="https://www.airpair.com/java/posts/spring-streams-memory-efficiency" rel="noreferrer">this article</a>, I wish to use Spring to stream database query results directly to a JSON response to ensure constant-memory usage (no greedy loading of a <code>List</code> in memory).</p>
  
  <p>Similar to what is done in the article with Hibernate, I assembled a <code>greetingRepository</code> object which returns a stream of the database contents based on a <code>JdbcTemplate</code>. In that implementation, I create an iterator over the queried <code>ResultSet</code>, and I return the stream as follows:</p>
  
  <pre><code>return StreamSupport.stream(spliterator(), false).onClose(() -&gt; {
    log.info("Closing ResultSetIterator stream");
    JdbcUtils.closeResultSet(resultSet);
  });
  </code></pre>
  
  <p>i.e. with an <code>onClose()</code> method guaranteeing that the underlying <code>ResultSet</code> will be closed if the stream is declared in a <code>try-with-resources</code> construct:</p>
  
  <pre><code>try(Stream&lt;Greeting&gt; stream = greetingRepository.stream()) {
    // operate on the stream
  } // ResultSet underlying the stream will be guaranteed to be closed
  </code></pre>
  
  <p>But as in the article, I want this stream to be consumed by a custom object mapper (the enhanced <code>MappingJackson2HttpMessageConverter</code> defined in the article). If we take the <code>try-with-resources</code> need aside, this is feasible as follows:</p>
  
  <pre><code>@RequestMapping(method = GET)
  Stream&lt;GreetingResource&gt; stream() {
    return greetingRepository.stream().map(GreetingResource::new);
  }
  </code></pre>
  
  <p>However as a colleague commented at the bottom of that article, this does not take care of closing underlying resources.</p>
  
  <p>In the context of Spring MVC, how can I stream from the database all the way into a JSON response and still guarantee that the <code>ResultSet</code> will be closed? Could you provide a concrete example solution?</p>