4
4
*/
5
5
package org .hibernate .orm .test .stream .basic ;
6
6
7
- import java .util .concurrent .atomic .AtomicInteger ;
8
- import java .util .stream .Stream ;
9
-
10
- import org .hibernate .engine .spi .SessionImplementor ;
11
-
12
- import org .hibernate .testing .orm .junit .JiraKey ;
13
- import org .hibernate .testing .orm .junit .DomainModel ;
14
- import org .hibernate .testing .orm .junit .SessionFactory ;
15
- import org .hibernate .testing .orm .junit .SessionFactoryScope ;
16
- import org .junit .jupiter .api .Test ;
17
-
18
7
import jakarta .persistence .Entity ;
19
8
import jakarta .persistence .Id ;
20
9
import jakarta .persistence .Table ;
21
10
import jakarta .persistence .Tuple ;
22
11
import jakarta .persistence .criteria .CriteriaBuilder ;
23
12
import jakarta .persistence .criteria .CriteriaQuery ;
24
13
import jakarta .persistence .criteria .Root ;
14
+ import org .hibernate .internal .util .MutableInteger ;
15
+ import org .hibernate .query .spi .QueryImplementor ;
16
+ import org .hibernate .testing .orm .junit .DomainModel ;
17
+ import org .hibernate .testing .orm .junit .JiraKey ;
18
+ import org .hibernate .testing .orm .junit .SessionFactory ;
19
+ import org .hibernate .testing .orm .junit .SessionFactoryScope ;
20
+ import org .junit .jupiter .api .AfterEach ;
21
+ import org .junit .jupiter .api .BeforeEach ;
22
+ import org .junit .jupiter .api .Test ;
23
+
24
+ import java .util .stream .Stream ;
25
25
26
26
import static org .hamcrest .MatcherAssert .assertThat ;
27
27
import static org .hamcrest .core .Is .is ;
31
31
/**
32
32
* @author Steve Ebersole
33
33
*/
34
- @ DomainModel (
35
- annotatedClasses = BasicStreamTest .MyEntity .class
36
- )
34
+ @ SuppressWarnings ("JUnitMalformedDeclaration" )
35
+ @ DomainModel ( annotatedClasses = BasicStreamTest .MyEntity .class )
37
36
@ SessionFactory
38
37
public class BasicStreamTest {
39
38
39
+ @ BeforeEach
40
+ void createTestData (SessionFactoryScope scope ) {
41
+ scope .inTransaction ( (session ) -> {
42
+ MyEntity e = new MyEntity ();
43
+ e .id = 1 ;
44
+ e .name = "Test" ;
45
+ session .persist ( e );
46
+ } );
47
+ }
48
+
49
+ @ AfterEach
50
+ void dropTestData (SessionFactoryScope scope ) {
51
+ scope .dropData ();
52
+ }
53
+
40
54
@ Test
41
- public void basicStreamTest (SessionFactoryScope scope ) {
42
-
43
- scope .inTransaction (
44
- session -> {
45
- // mainly we want to make sure that closing the Stream releases the ScrollableResults too
46
- assertThat ( ( (SessionImplementor ) session ).getJdbcCoordinator ()
47
- .getLogicalConnection ()
48
- .getResourceRegistry ()
49
- .hasRegisteredResources (), is ( false ) );
50
- final Stream <MyEntity > stream = session .createQuery ( "from MyEntity" , MyEntity .class ).stream ();
51
- try {
52
- stream .forEach ( System .out ::println );
53
- assertThat ( session .getJdbcCoordinator ()
54
- .getLogicalConnection ()
55
- .getResourceRegistry ()
56
- .hasRegisteredResources (), is ( true ) );
57
- }
58
- finally {
59
- stream .close ();
60
- assertThat ( session .getJdbcCoordinator ()
61
- .getLogicalConnection ()
62
- .getResourceRegistry ()
63
- .hasRegisteredResources (), is ( false ) );
64
- }
65
-
66
- }
67
- );
55
+ public void testBasicStreamHandling (SessionFactoryScope scope ) {
56
+ // make sure that closing the Stream releases the ScrollableResults too
57
+ scope .inTransaction ( (session ) -> {
58
+ // at start, we should have no registered resources
59
+ assertThat ( session .getJdbcCoordinator ()
60
+ .getLogicalConnection ()
61
+ .getResourceRegistry ()
62
+ .hasRegisteredResources (), is ( false ) );
63
+
64
+ final Stream <MyEntity > stream = session .createQuery ( "from MyEntity" , MyEntity .class ).stream ();
65
+ //noinspection TryFinallyCanBeTryWithResources
66
+ try {
67
+ stream .forEach ( System .out ::println );
68
+ // we should have registered resources here as the underlying ScrollableResults is still open
69
+ assertThat ( session .getJdbcCoordinator ()
70
+ .getLogicalConnection ()
71
+ .getResourceRegistry ()
72
+ .hasRegisteredResources (), is ( true ) );
73
+ }
74
+ finally {
75
+ stream .close ();
76
+ // after an explicit close, we should have no registered resources
77
+ assertThat ( session .getJdbcCoordinator ()
78
+ .getLogicalConnection ()
79
+ .getResourceRegistry ()
80
+ .hasRegisteredResources (), is ( false ) );
81
+ }
82
+
83
+ } );
68
84
}
69
85
70
86
@ Test
71
- @ JiraKey (value = "HHH-10824" )
72
- public void testQueryStream (SessionFactoryScope scope ) {
73
-
74
- scope .inTransaction (
75
- session -> {
76
- MyEntity e = new MyEntity ();
77
- e .id = 1 ;
78
- e .name = "Test" ;
79
- session .persist ( e );
80
- }
81
- );
82
-
83
- scope .inSession (
84
- session -> {
85
- // Test stream query without type.
86
- try (Stream stream = session .createQuery ( "From MyEntity" ).stream ()) {
87
- Object result = stream .findFirst ().orElse ( null );
88
- assertTyping ( MyEntity .class , result );
89
- }
90
-
91
- // Test stream query with type.
92
- try (final Stream <MyEntity > stream = session .createQuery ( "From MyEntity" , MyEntity .class )
93
- .stream ()) {
94
- assertTyping ( MyEntity .class , stream .findFirst ().orElse ( null ) );
95
- }
96
-
97
- // Test stream query using forEach
98
- try (Stream <MyEntity > stream = session .createQuery ( "From MyEntity" , MyEntity .class )
99
- .stream ()) {
100
- stream .forEach ( i -> {
101
- assertTyping ( MyEntity .class , i );
102
- } );
103
- }
104
-
105
- try (Stream <Object []> stream = session .createQuery ( "SELECT me.id, me.name FROM MyEntity me" )
106
- .stream ()) {
107
- stream .forEach ( i -> {
108
- assertTyping ( Integer .class , i [0 ] );
109
- assertTyping ( String .class , i [1 ] );
110
- } );
111
- }
112
- }
113
- );
87
+ public void testStreamAutoClosing (SessionFactoryScope scope ) {
88
+ // same as #testBasicStreamHandling but using try-with-resources
89
+
90
+ final MutableInteger onCloseCount = new MutableInteger ();
91
+
92
+ scope .inTransaction ( (session ) -> {
93
+ // at start, we should have no registered resources
94
+ assertThat ( session .getJdbcCoordinator ()
95
+ .getLogicalConnection ()
96
+ .getResourceRegistry ()
97
+ .hasRegisteredResources (), is ( false ) );
98
+ assertThat ( onCloseCount .get (), equalTo ( 0 ) );
99
+
100
+ final QueryImplementor <MyEntity > query = session .createQuery ( "from MyEntity" , MyEntity .class );
101
+ try ( final Stream <MyEntity > stream = query .stream ().onClose ( onCloseCount ::increment ) ) {
102
+ stream .forEach ( System .out ::println );
103
+
104
+ // we should have registered resources here as the underlying ScrollableResults is still open
105
+ assertThat ( session .getJdbcCoordinator ()
106
+ .getLogicalConnection ()
107
+ .getResourceRegistry ()
108
+ .hasRegisteredResources (), is ( true ) );
109
+ assertThat ( onCloseCount .get (), equalTo ( 0 ) );
110
+ }
111
+
112
+ assertThat ( session .getJdbcCoordinator ()
113
+ .getLogicalConnection ()
114
+ .getResourceRegistry ()
115
+ .hasRegisteredResources (), is ( false ) );
114
116
117
+ assertThat ( onCloseCount .get (), equalTo ( 1 ) );
118
+ } );
115
119
}
116
120
117
121
@ Test
118
- @ JiraKey (value = "HHH-11743" )
119
- public void testTupleStream (SessionFactoryScope scope ) {
120
- scope .inTransaction ( session -> {
121
- MyEntity entity = new MyEntity ();
122
- entity .id = 2 ;
123
- entity .name = "an entity" ;
124
- session .persist ( entity );
122
+ @ JiraKey (value = "HHH-10824" )
123
+ public void testQueryStreamTyping (SessionFactoryScope scope ) {
124
+ // Test untyped query stream
125
+ scope .inTransaction ( (session ) -> {
126
+ try (Stream stream = session .createQuery ( "from MyEntity" ).stream ()) {
127
+ Object result = stream .findFirst ().orElse ( null );
128
+ assertTyping ( MyEntity .class , result );
129
+ }
130
+ } );
131
+
132
+ // Test typed query stream
133
+ scope .inTransaction ( (session ) -> {
134
+ try (final Stream <MyEntity > stream = session .createQuery ( "from MyEntity" , MyEntity .class ).stream ()) {
135
+ assertTyping ( MyEntity .class , stream .findFirst ().orElse ( null ) );
136
+ }
137
+ } );
138
+
139
+ // Test stream query using forEach
140
+ scope .inTransaction ( (session ) -> {
141
+ try (Stream <MyEntity > stream = session .createQuery ( "from MyEntity" , MyEntity .class ).stream ()) {
142
+ stream .forEach ( i -> {
143
+ assertTyping ( MyEntity .class , i );
144
+ } );
145
+ }
146
+ } );
147
+
148
+ // Test stream query with Object[] result
149
+ scope .inTransaction ( (session ) -> {
150
+ try (Stream <Object []> stream = session .createQuery ( "SELECT me.id, me.name from MyEntity me" ).stream ()) {
151
+ stream .forEach ( i -> {
152
+ assertTyping ( Integer .class , i [0 ] );
153
+ assertTyping ( String .class , i [1 ] );
154
+ } );
155
+ }
125
156
} );
126
157
127
158
//test tuple stream using criteria
@@ -144,45 +175,6 @@ public void testTupleStream(SessionFactoryScope scope) {
144
175
} );
145
176
}
146
177
147
- @ Test
148
- public void basicStreamTestWithExplicitOnClose (SessionFactoryScope scope ) {
149
- scope .inTransaction (
150
- session -> {
151
- AtomicInteger onCloseCount = new AtomicInteger ();
152
-
153
- // mainly we want to make sure that closing the Stream releases the ScrollableResults too
154
- assertThat ( session .getJdbcCoordinator ()
155
- .getLogicalConnection ()
156
- .getResourceRegistry ()
157
- .hasRegisteredResources (), is ( false ) );
158
-
159
- assertThat ( onCloseCount .get (), equalTo ( 0 ) );
160
-
161
- try (final Stream <MyEntity > stream = session .createQuery ( "from MyEntity" , MyEntity .class )
162
- .stream ()
163
- .onClose (
164
- onCloseCount ::incrementAndGet )) {
165
-
166
-
167
- assertThat ( onCloseCount .get (), equalTo ( 0 ) );
168
-
169
- stream .forEach ( System .out ::println );
170
- assertThat ( session .getJdbcCoordinator ()
171
- .getLogicalConnection ()
172
- .getResourceRegistry ()
173
- .hasRegisteredResources (), is ( true ) );
174
- }
175
-
176
- assertThat ( session .getJdbcCoordinator ()
177
- .getLogicalConnection ()
178
- .getResourceRegistry ()
179
- .hasRegisteredResources (), is ( false ) );
180
-
181
- assertThat ( onCloseCount .get (), equalTo ( 1 ) );
182
- }
183
- );
184
- }
185
-
186
178
@ Entity (name = "MyEntity" )
187
179
@ Table (name = "MyEntity" )
188
180
public static class MyEntity {
0 commit comments