18
18
import static org .assertj .core .api .Assertions .*;
19
19
import static org .mockito .Mockito .*;
20
20
21
+ import java .lang .reflect .Method ;
21
22
import java .sql .ResultSet ;
23
+ import java .util .List ;
24
+ import java .util .Properties ;
22
25
23
26
import org .assertj .core .api .Assertions ;
24
27
import org .junit .jupiter .api .BeforeEach ;
25
28
import org .junit .jupiter .api .Test ;
26
29
27
30
import org .springframework .dao .DataAccessException ;
31
+ import org .springframework .data .domain .Page ;
32
+ import org .springframework .data .domain .Pageable ;
33
+ import org .springframework .data .domain .Slice ;
28
34
import org .springframework .data .jdbc .core .convert .BasicJdbcConverter ;
29
35
import org .springframework .data .jdbc .core .convert .JdbcConverter ;
30
36
import org .springframework .data .jdbc .core .convert .RelationResolver ;
37
+ import org .springframework .data .projection .SpelAwareProxyProjectionFactory ;
31
38
import org .springframework .data .relational .core .mapping .RelationalMappingContext ;
32
- import org .springframework .data .relational . repository .query . RelationalParameters ;
33
- import org .springframework .data .repository .query . DefaultParameters ;
34
- import org .springframework .data .repository .query . Parameters ;
39
+ import org .springframework .data .repository .Repository ;
40
+ import org .springframework .data .repository .core . support . DefaultRepositoryMetadata ;
41
+ import org .springframework .data .repository .core . support . PropertiesBasedNamedQueries ;
35
42
import org .springframework .jdbc .core .ResultSetExtractor ;
36
43
import org .springframework .jdbc .core .RowMapper ;
37
44
import org .springframework .jdbc .core .namedparam .NamedParameterJdbcOperations ;
45
+ import org .springframework .util .ReflectionUtils ;
38
46
39
47
/**
40
48
* Unit tests for {@link StringBasedJdbcQuery}.
47
55
*/
48
56
public class StringBasedJdbcQueryUnitTests {
49
57
50
- JdbcQueryMethod queryMethod ;
51
58
52
59
RowMapper <Object > defaultRowMapper ;
53
60
NamedParameterJdbcOperations operations ;
@@ -57,12 +64,6 @@ public class StringBasedJdbcQueryUnitTests {
57
64
@ BeforeEach
58
65
public void setup () throws NoSuchMethodException {
59
66
60
- this .queryMethod = mock (JdbcQueryMethod .class );
61
-
62
- Parameters <?, ?> parameters = new RelationalParameters (
63
- StringBasedJdbcQueryUnitTests .class .getDeclaredMethod ("dummyMethod" ));
64
- doReturn (parameters ).when (queryMethod ).getParameters ();
65
-
66
67
this .defaultRowMapper = mock (RowMapper .class );
67
68
this .operations = mock (NamedParameterJdbcOperations .class );
68
69
this .context = mock (RelationalMappingContext .class , RETURNS_DEEP_STUBS );
@@ -72,58 +73,36 @@ public void setup() throws NoSuchMethodException {
72
73
@ Test // DATAJDBC-165
73
74
public void emptyQueryThrowsException () {
74
75
75
- doReturn ( null ). when ( queryMethod ). getDeclaredQuery ( );
76
+ JdbcQueryMethod queryMethod = createMethod ( "noAnnotation" );
76
77
77
78
Assertions .assertThatExceptionOfType (IllegalStateException .class ) //
78
- .isThrownBy (() -> createQuery ()
79
+ .isThrownBy (() -> createQuery (queryMethod )
79
80
.execute (new Object [] {}));
80
81
}
81
82
82
- private StringBasedJdbcQuery createQuery () {
83
-
84
- StringBasedJdbcQuery query = new StringBasedJdbcQuery (queryMethod , operations , defaultRowMapper , converter );
85
- return query ;
86
- }
87
-
88
83
@ Test // DATAJDBC-165
89
84
public void defaultRowMapperIsUsedByDefault () {
90
85
91
- doReturn ("some sql statement" ).when (queryMethod ).getDeclaredQuery ();
92
- doReturn (RowMapper .class ).when (queryMethod ).getRowMapperClass ();
93
- StringBasedJdbcQuery query = createQuery ();
94
-
95
- assertThat (query .determineRowMapper (defaultRowMapper )).isEqualTo (defaultRowMapper );
96
- }
97
-
98
- @ Test // DATAJDBC-165, DATAJDBC-318
99
- public void defaultRowMapperIsUsedForNull () {
100
-
101
- doReturn ("some sql statement" ).when (queryMethod ).getDeclaredQuery ();
102
- StringBasedJdbcQuery query = createQuery ();
86
+ JdbcQueryMethod queryMethod = createMethod ("findAll" );
87
+ StringBasedJdbcQuery query = createQuery (queryMethod );
103
88
104
89
assertThat (query .determineRowMapper (defaultRowMapper )).isEqualTo (defaultRowMapper );
105
90
}
106
91
107
92
@ Test // DATAJDBC-165, DATAJDBC-318
108
93
public void customRowMapperIsUsedWhenSpecified () {
109
94
110
- doReturn ("some sql statement" ).when (queryMethod ).getDeclaredQuery ();
111
- doReturn (CustomRowMapper .class ).when (queryMethod ).getRowMapperClass ();
112
-
113
- StringBasedJdbcQuery query = createQuery ();
95
+ JdbcQueryMethod queryMethod = createMethod ("findAllWithCustomRowMapper" );
96
+ StringBasedJdbcQuery query = createQuery (queryMethod );
114
97
115
98
assertThat (query .determineRowMapper (defaultRowMapper )).isInstanceOf (CustomRowMapper .class );
116
99
}
117
100
118
101
@ Test // DATAJDBC-290
119
102
public void customResultSetExtractorIsUsedWhenSpecified () {
120
103
121
- doReturn ("some sql statement" ).when (queryMethod ).getDeclaredQuery ();
122
- doReturn (CustomResultSetExtractor .class ).when (queryMethod ).getResultSetExtractorClass ();
123
-
124
- createQuery ().execute (new Object [] {});
125
-
126
- StringBasedJdbcQuery query = createQuery ();
104
+ JdbcQueryMethod queryMethod = createMethod ("findAllWithCustomResultSetExtractor" );
105
+ StringBasedJdbcQuery query = createQuery (queryMethod );
127
106
128
107
ResultSetExtractor <Object > resultSetExtractor = query .determineResultSetExtractor (defaultRowMapper );
129
108
@@ -136,11 +115,8 @@ public void customResultSetExtractorIsUsedWhenSpecified() {
136
115
@ Test // DATAJDBC-290
137
116
public void customResultSetExtractorAndRowMapperGetCombined () {
138
117
139
- doReturn ("some sql statement" ).when (queryMethod ).getDeclaredQuery ();
140
- doReturn (CustomResultSetExtractor .class ).when (queryMethod ).getResultSetExtractorClass ();
141
- doReturn (CustomRowMapper .class ).when (queryMethod ).getRowMapperClass ();
142
-
143
- StringBasedJdbcQuery query = createQuery ();
118
+ JdbcQueryMethod queryMethod = createMethod ("findAllWithCustomRowMapperAndResultSetExtractor" );
119
+ StringBasedJdbcQuery query = createQuery (queryMethod );
144
120
145
121
ResultSetExtractor <Object > resultSetExtractor = query
146
122
.determineResultSetExtractor (query .determineRowMapper (defaultRowMapper ));
@@ -151,11 +127,61 @@ public void customResultSetExtractorAndRowMapperGetCombined() {
151
127
"RowMapper is not expected to be custom" );
152
128
}
153
129
154
- /**
155
- * The whole purpose of this method is to easily generate a {@link DefaultParameters} instance during test setup.
156
- */
157
- @ SuppressWarnings ("unused" )
158
- private void dummyMethod () {}
130
+ @ Test // GH-774
131
+ public void sliceQueryNotSupported () {
132
+
133
+ JdbcQueryMethod queryMethod = createMethod ("sliceAll" , Pageable .class );
134
+
135
+ assertThatThrownBy (() -> new StringBasedJdbcQuery (queryMethod , operations , defaultRowMapper , converter ))
136
+ .isInstanceOf (UnsupportedOperationException .class )
137
+ .hasMessageContaining ("Slice queries are not supported using string-based queries" );
138
+ }
139
+
140
+ @ Test // GH-774
141
+ public void pageQueryNotSupported () {
142
+
143
+ JdbcQueryMethod queryMethod = createMethod ("pageAll" , Pageable .class );
144
+
145
+ assertThatThrownBy (() -> new StringBasedJdbcQuery (queryMethod , operations , defaultRowMapper , converter ))
146
+ .isInstanceOf (UnsupportedOperationException .class )
147
+ .hasMessageContaining ("Page queries are not supported using string-based queries" );
148
+ }
149
+
150
+ private JdbcQueryMethod createMethod (String methodName , Class <?>... paramTypes ) {
151
+
152
+ Method method = ReflectionUtils .findMethod (MyRepository .class , methodName , paramTypes );
153
+ return new JdbcQueryMethod (method , new DefaultRepositoryMetadata (MyRepository .class ),
154
+ new SpelAwareProxyProjectionFactory (), new PropertiesBasedNamedQueries (new Properties ()), this .context );
155
+ }
156
+
157
+ private StringBasedJdbcQuery createQuery (JdbcQueryMethod queryMethod ) {
158
+ return new StringBasedJdbcQuery (queryMethod , operations , defaultRowMapper , converter );
159
+ }
160
+
161
+ interface MyRepository extends Repository <Object , Long > {
162
+
163
+ @ Query (value = "some sql statement" )
164
+ List <Object > findAll ();
165
+
166
+ @ Query (value = "some sql statement" , rowMapperClass = CustomRowMapper .class )
167
+ List <Object > findAllWithCustomRowMapper ();
168
+
169
+ @ Query (value = "some sql statement" , resultSetExtractorClass = CustomResultSetExtractor .class )
170
+ List <Object > findAllWithCustomResultSetExtractor ();
171
+
172
+ @ Query (value = "some sql statement" , rowMapperClass = CustomRowMapper .class ,
173
+ resultSetExtractorClass = CustomResultSetExtractor .class )
174
+ List <Object > findAllWithCustomRowMapperAndResultSetExtractor ();
175
+
176
+ List <Object > noAnnotation ();
177
+
178
+ @ Query (value = "some sql statement" )
179
+ Page <Object > pageAll (Pageable pageable );
180
+
181
+ @ Query (value = "some sql statement" )
182
+ Slice <Object > sliceAll (Pageable pageable );
183
+
184
+ }
159
185
160
186
private static class CustomRowMapper implements RowMapper <Object > {
161
187
0 commit comments