Skip to content

Commit b4bf581

Browse files
juja0sebersole
authored andcommitted
HHH-14449 : ResultStream closing is not properly handled
1 parent 5324db9 commit b4bf581

File tree

7 files changed

+338
-49
lines changed

7 files changed

+338
-49
lines changed

hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,12 +1584,10 @@ public Stream<R> stream() {
15841584
final ScrollableResultsIterator<R> iterator = new ScrollableResultsIterator<>( scrollableResults );
15851585
final Spliterator<R> spliterator = Spliterators.spliteratorUnknownSize( iterator, Spliterator.NONNULL );
15861586

1587-
final Stream<R> stream = new StreamDecorator(
1587+
return new StreamDecorator<>(
15881588
StreamSupport.stream( spliterator, false ),
1589-
scrollableResults::close
1589+
iterator::close
15901590
);
1591-
1592-
return stream;
15931591
}
15941592

15951593
@Override

hibernate-core/src/main/java/org/hibernate/query/spi/DoubleStreamDecorator.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,13 @@
4141
public class DoubleStreamDecorator implements DoubleStream {
4242

4343
private final DoubleStream delegate;
44-
45-
private Runnable closeHandler;
44+
private final Runnable closeHandler;
4645

4746
public DoubleStreamDecorator(
4847
DoubleStream delegate,
4948
Runnable closeHandler) {
50-
this.delegate = delegate;
5149
this.closeHandler = closeHandler;
52-
this.delegate.onClose( closeHandler );
50+
this.delegate = delegate.onClose( closeHandler );
5351
}
5452

5553
@Override
@@ -292,7 +290,7 @@ public DoubleStream unordered() {
292290

293291
@Override
294292
public DoubleStream onClose(Runnable closeHandler) {
295-
this.closeHandler = closeHandler;
293+
this.delegate.onClose( closeHandler );
296294
return this;
297295
}
298296

hibernate-core/src/main/java/org/hibernate/query/spi/IntStreamDecorator.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,13 @@
4242
public class IntStreamDecorator implements IntStream {
4343

4444
private final IntStream delegate;
45-
46-
private Runnable closeHandler;
45+
private final Runnable closeHandler;
4746

4847
public IntStreamDecorator(
4948
IntStream delegate,
5049
Runnable closeHandler) {
51-
this.delegate = delegate;
5250
this.closeHandler = closeHandler;
53-
this.delegate.onClose( closeHandler );
51+
this.delegate = delegate.onClose( closeHandler );
5452
}
5553

5654
@Override
@@ -307,7 +305,7 @@ public IntStream unordered() {
307305

308306
@Override
309307
public IntStream onClose(Runnable closeHandler) {
310-
this.closeHandler = closeHandler;
308+
this.delegate.onClose( closeHandler );
311309
return this;
312310
}
313311

hibernate-core/src/main/java/org/hibernate/query/spi/LongStreamDecorator.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,13 @@
4242
public class LongStreamDecorator implements LongStream {
4343

4444
private final LongStream delegate;
45-
46-
private Runnable closeHandler;
45+
private final Runnable closeHandler;
4746

4847
public LongStreamDecorator(
4948
LongStream delegate,
5049
Runnable closeHandler) {
51-
this.delegate = delegate;
5250
this.closeHandler = closeHandler;
53-
this.delegate.onClose( closeHandler );
51+
this.delegate = delegate.onClose( closeHandler );
5452
}
5553

5654
@Override
@@ -226,21 +224,21 @@ public LongSummaryStatistics summaryStatistics() {
226224

227225
@Override
228226
public boolean anyMatch(LongPredicate predicate) {
229-
boolean result = delegate.anyMatch(predicate);
227+
boolean result = delegate.anyMatch( predicate );
230228
close();
231229
return result;
232230
}
233231

234232
@Override
235233
public boolean allMatch(LongPredicate predicate) {
236-
boolean result = delegate.allMatch(predicate);
234+
boolean result = delegate.allMatch( predicate );
237235
close();
238236
return result;
239237
}
240238

241239
@Override
242240
public boolean noneMatch(LongPredicate predicate) {
243-
boolean result = delegate.noneMatch(predicate);
241+
boolean result = delegate.noneMatch( predicate );
244242
close();
245243
return result;
246244
}
@@ -300,7 +298,7 @@ public LongStream unordered() {
300298

301299
@Override
302300
public LongStream onClose(Runnable closeHandler) {
303-
this.closeHandler = closeHandler;
301+
this.delegate.onClose( closeHandler );
304302
return this;
305303
}
306304

hibernate-core/src/main/java/org/hibernate/query/spi/StreamDecorator.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,13 @@
4646
public class StreamDecorator<R> implements Stream<R> {
4747

4848
private final Stream<R> delegate;
49-
50-
private Runnable closeHandler;
49+
private final Runnable closeHandler;
5150

5251
public StreamDecorator(
5352
Stream<R> delegate,
5453
Runnable closeHandler) {
55-
this.delegate = delegate;
5654
this.closeHandler = closeHandler;
57-
this.delegate.onClose( closeHandler );
55+
this.delegate = delegate.onClose( closeHandler );
5856
}
5957

6058
@Override
@@ -301,7 +299,7 @@ public Stream<R> unordered() {
301299

302300
@Override
303301
public Stream<R> onClose(Runnable closeHandler) {
304-
this.closeHandler = closeHandler;
302+
this.delegate.onClose( closeHandler );
305303
return this;
306304
}
307305

hibernate-core/src/test/java/org/hibernate/test/stream/basic/BasicStreamTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
package org.hibernate.test.stream.basic;
88

9+
import java.util.concurrent.atomic.AtomicInteger;
910
import java.util.stream.Stream;
1011
import javax.persistence.Entity;
1112
import javax.persistence.Id;
@@ -25,6 +26,7 @@
2526

2627
import static org.hamcrest.MatcherAssert.assertThat;
2728
import static org.hamcrest.core.Is.is;
29+
import static org.hamcrest.core.IsEqual.equalTo;
2830
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
2931
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
3032

@@ -123,6 +125,53 @@ public void testTupleStream() {
123125
} );
124126
}
125127

128+
@Test
129+
public void basicStreamTestWithExplicitOnClose() {
130+
Session session = openSession();
131+
session.getTransaction().begin();
132+
133+
AtomicInteger onCloseCount = new AtomicInteger();
134+
135+
// mainly we want to make sure that closing the Stream releases the ScrollableResults too
136+
assertThat( ( (SessionImplementor) session ).getJdbcCoordinator()
137+
.getLogicalConnection()
138+
.getResourceRegistry()
139+
.hasRegisteredResources(), is( false ) );
140+
141+
assertThat( onCloseCount.get(), equalTo( 0 ) );
142+
143+
final Stream<MyEntity> stream = session.createQuery( "from MyEntity", MyEntity.class ).stream().onClose(
144+
onCloseCount::incrementAndGet );
145+
146+
assertThat( ( (SessionImplementor) session ).getJdbcCoordinator()
147+
.getLogicalConnection()
148+
.getResourceRegistry()
149+
.hasRegisteredResources(), is( true ) );
150+
151+
assertThat( onCloseCount.get(), equalTo( 0 ) );
152+
153+
stream.forEach( System.out::println );
154+
155+
assertThat( ( (SessionImplementor) session ).getJdbcCoordinator()
156+
.getLogicalConnection()
157+
.getResourceRegistry()
158+
.hasRegisteredResources(), is( false ) );
159+
160+
assertThat( onCloseCount.get(), equalTo( 1 ) );
161+
162+
stream.close();
163+
164+
assertThat( ( (SessionImplementor) session ).getJdbcCoordinator()
165+
.getLogicalConnection()
166+
.getResourceRegistry()
167+
.hasRegisteredResources(), is( false ) );
168+
169+
assertThat( onCloseCount.get(), equalTo( 1 ) );
170+
171+
session.getTransaction().commit();
172+
session.close();
173+
}
174+
126175
@Entity(name = "MyEntity")
127176
@Table(name="MyEntity")
128177
public static class MyEntity {

0 commit comments

Comments
 (0)