users@jpa-spec.java.net

[jpa-spec users] Re: JPA_SPEC-99: Add ability to stream the result of a query execution

From: Rob Bygrave <rbygrave_at_yahoo.com>
Date: Fri, 5 May 2017 17:25:18 +1200

*> and provided with default implementation:*

If a "streaming query" implies the ability to handle potentially large
resultSets. The implication for the ORM implementation would be:
- JDBC hints are used to ensure the JDBC driver also streams results
(unlike default behavior)
- A different persistence context scope is used (to support streaming
millions of object graphs without blowing out memory)

As such to me the default implementation of: getResultList().stream() ...
is a rather dangerous implementation.


Cheers, Rob.


On 5 May 2017 at 17:10, Rob Bygrave <rbygrave_at_yahoo.com> wrote:

> Note that Stream is AutoCloseable but that developers absolutely must
> remember to close the stream (try with resources).
>
> As such I'd suggest there is a case for additionally considering:
>
> findEach(Consumer<T> consumer)
> findEachWhile(Predicate<T> consumer)
>
> ... which removes any possibility of resource leaking.
>
>
> On 5 May 2017 at 11:34, Michael Nascimento <misterm_at_gmail.com> wrote:
>
>> Sounds better, for sure.
>>
>> Regards,
>> Michael
>>
>> On Thu, May 4, 2017 at 7:56 PM, Steve Ebersole <steve_at_hibernate.org>
>> wrote:
>>
>>> Can we call it #stream instead of #getResultStream? This would be more
>>> consistent with other steaming calls in Java
>>>
>>> On Thu, May 4, 2017, 4:40 PM Michael Nascimento <misterm_at_gmail.com>
>>> wrote:
>>>
>>>> This change seems very valuable and welcome, for sure.
>>>>
>>>> Regards,
>>>> Michael
>>>>
>>>>
>>>> On Thu, May 4, 2017 at 5:01 PM, Lukas Jungmann <
>>>> lukas.jungmann_at_oracle.com> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> another change I'd like to propose is an addition of
>>>>> getResultStream:Stream method to javax.persistence.Query/TypedQuery
>>>>> interfaces with following javadoc and provided with default implementation:
>>>>>
>>>>> javax.persistence.Query:
>>>>>
>>>>> * /***
>>>>> * * Execute a SELECT query and return the query results*
>>>>> * * as an untyped <code>java.util.Stream</code>.*
>>>>> * * By default this method delegates to
>>>>> <code>getResultList().stream()</code>,*
>>>>> * * however persistence provider may choose to override this
>>>>> method*
>>>>> * * to provide additional capabilities.*
>>>>> * **
>>>>> * * @return a stream of the results*
>>>>> * * @throws IllegalStateException if called for a Java*
>>>>> * * Persistence query language UPDATE or DELETE statement*
>>>>> * * @throws QueryTimeoutException if the query execution exceeds*
>>>>> * * the query timeout value set and only the statement is*
>>>>> * * rolled back*
>>>>> * * @throws TransactionRequiredException if a lock mode other than*
>>>>> * * <code>NONE</code> has been set and there is no
>>>>> transaction*
>>>>> * * or the persistence context has not been joined to the
>>>>> transaction*
>>>>> * * @throws PessimisticLockException if pessimistic locking*
>>>>> * * fails and the transaction is rolled back*
>>>>> * * @throws LockTimeoutException if pessimistic locking*
>>>>> * * fails and only the statement is rolled back*
>>>>> * * @throws PersistenceException if the query execution exceeds *
>>>>> * * the query timeout value set and the transaction *
>>>>> * * is rolled back *
>>>>> * * @see Stream*
>>>>> * * @see #getResultList()*
>>>>> * * @since 2.2*
>>>>> * */*
>>>>> * default Stream getResultStream() {*
>>>>> * return getResultList().stream();*
>>>>> * }*
>>>>>
>>>>> similarly to javax.persistence.TypedQuery:
>>>>>
>>>>> * /***
>>>>> * * Execute a SELECT query and return the query results*
>>>>> * * as a typed <code>java.util.Stream</code>.*
>>>>> * * By default this method delegates to
>>>>> <code>getResultList().stream()</code>,*
>>>>> * * however persistence provider may choose to override this
>>>>> method*
>>>>> * * to provide additional capabilities.*
>>>>> * **
>>>>> * * @return a stream of the results*
>>>>> * * @throws IllegalStateException if called for a Java*
>>>>> * * Persistence query language UPDATE or DELETE statement*
>>>>> * * @throws QueryTimeoutException if the query execution exceeds*
>>>>> * * the query timeout value set and only the statement is*
>>>>> * * rolled back*
>>>>> * * @throws TransactionRequiredException if a lock mode other than*
>>>>> * * <code>NONE</code> has been set and there is no
>>>>> transaction*
>>>>> * * or the persistence context has not been joined to the
>>>>> transaction*
>>>>> * * @throws PessimisticLockException if pessimistic locking*
>>>>> * * fails and the transaction is rolled back*
>>>>> * * @throws LockTimeoutException if pessimistic locking*
>>>>> * * fails and only the statement is rolled back*
>>>>> * * @throws PersistenceException if the query execution exceeds *
>>>>> * * the query timeout value set and the transaction *
>>>>> * * is rolled back *
>>>>> * * @see Stream*
>>>>> * * @see #getResultList()*
>>>>> * * @since 2.2*
>>>>> * */*
>>>>> * default Stream<X> getResultStream() {*
>>>>> * return getResultList().stream();*
>>>>> * }*
>>>>>
>>>>> Do you think this is OK or does it give providers to big freedom?
>>>>>
>>>>> Thank you,
>>>>> --lukas
>>>>>
>>>>
>>>>
>>
>