8

Why don't we have java 8 stream support in MongoTemplate in spring-data-mongodb-1.8.2.RELEASE.jar ?

I see that stream support have bean added in MongoRepository interface but I use pure MongoTemplate.

poyger
  • 636
  • 2
  • 8
  • 17

2 Answers2

19

In short

There is stream support but without exposing Stream on MongoOperations.

Explanation

Spring Data Mongo has stream support by exposing CloseableIterator<T> stream(final Query query, final Class<T> entityType). It does not use the Stream type on MongoOperations because Spring Data Mongo supports Java back to 1.6. You can obtain the Stream object by using StreamUtils.createStreamFromIterator(Iterator<T>). StreamUtils takes care of closing the stream and releasing resources.

HTH, Mark

mp911de
  • 17,546
  • 2
  • 55
  • 95
  • 1
    that worked, thanks. What is best practice for my use case, I want to limit the resultset and sort it, is it better to do that in the mongo query or return an stream to caller and let it do the limit and sort with Java 8 functionality. Does the stream option do a lot of IO ? – poyger Feb 23 '16 at 09:14
  • It depends on data size and which properties are indexed. If you can do it within MongoDB (enough capacity, properties are indexed, quite a lot of data to sort/filter) then do it within the MongoDB query. If you deal only with a couple of records that would occupy the MongoDB instance more than your Java code, then it's probably better to limit/sort within the stream itself. – mp911de Feb 23 '16 at 09:57
  • Unfortunately there is no stream method on GridFsTemplate, only on MongoTemplate... What's the best way to obtain a true Stream then ? – Olivier Gérardin Oct 31 '18 at 17:00
  • Answering my own question: this is what you need to do to get a Stream: `GridFSFindIterable fsFindIterable = gridFsTemplate.find(new Query()); Stream stream = StreamUtils.createStreamFromIterator(fsFindIterable.iterator());` – Olivier Gérardin Nov 05 '18 at 13:03
8

Mark's answer is correct (and should stay the accepted answer). Maybe a few more details on why you don't find a Stream on the MongoTemplate:

The core reason that there's no Stream on the MongoTemplate level is that Spring Data MongoDB is still compatible with Java 6. So we can't use Java 8 types in method signatures of classes we provide. With repositories, it's a different story as that's user code we inspect at runtime and — if Java 8 is present — dynamically adapt to, e.g. by converting the CloseableIterator<T> into a Stream.

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
  • thanks for the explanation, intresseting, can you point me where in the spring code you do that java 8 adaption for Repositories, I am just curious to see how it works under the hood. – poyger Feb 23 '16 at 17:09
  • For `Stream`s it's easy as we can just detect the return type and use a [`Stream` specific execution](https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryExecution.java#L303). The reflection bits are in [Spring Data Commons](https://github.com/spring-projects/spring-data-commons/blob/master/src/main/java/org/springframework/data/repository/query/QueryMethod.java#L224). The trick is basically to make sure you don't load any classes with Java 8 types on older VMS (using reflection guards) – Oliver Drotbohm Feb 23 '16 at 17:15