1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.submitted.keygen;
17
18 import static com.googlecode.catchexception.apis.BDDCatchException.caughtException;
19 import static com.googlecode.catchexception.apis.BDDCatchException.when;
20 import static org.assertj.core.api.BDDAssertions.then;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23
24 import java.io.Reader;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.ibatis.BaseDataTest;
34 import org.apache.ibatis.exceptions.PersistenceException;
35 import org.apache.ibatis.io.Resources;
36 import org.apache.ibatis.session.ExecutorType;
37 import org.apache.ibatis.session.SqlSession;
38 import org.apache.ibatis.session.SqlSessionFactory;
39 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
40 import org.junit.jupiter.api.BeforeAll;
41 import org.junit.jupiter.api.Test;
42
43
44
45
46 class Jdbc3KeyGeneratorTest {
47
48 private static SqlSessionFactory sqlSessionFactory;
49
50 @BeforeAll
51 static void setUp() throws Exception {
52
53 try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/keygen/MapperConfig.xml")) {
54 sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
55 }
56
57
58 BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
59 "org/apache/ibatis/submitted/keygen/CreateDB.sql");
60 }
61
62 @Test
63 void shouldAssignKeyToBean() {
64 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
65 try {
66 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
67 Country country = new Country("China", "CN");
68 mapper.insertBean(country);
69 assertNotNull(country.getId());
70 } finally {
71 sqlSession.rollback();
72 }
73 }
74 }
75
76 @Test
77 void shouldAssignKeyToBean_batch() {
78 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
79 try {
80 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
81 Country country1 = new Country("China", "CN");
82 mapper.insertBean(country1);
83 Country country2 = new Country("Canada", "CA");
84 mapper.insertBean(country2);
85 sqlSession.flushStatements();
86 sqlSession.clearCache();
87 assertNotNull(country1.getId());
88 assertNotNull(country2.getId());
89 } finally {
90 sqlSession.rollback();
91 }
92 }
93 }
94
95 @Test
96 void shouldAssignKeyToNamedBean() {
97 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
98 try {
99 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
100 Country country = new Country("China", "CN");
101 mapper.insertNamedBean(country);
102 assertNotNull(country.getId());
103 } finally {
104 sqlSession.rollback();
105 }
106 }
107 }
108
109 @Test
110 void shouldAssignKeyToNamedBean_batch() {
111 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
112 try {
113 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
114 Country country1 = new Country("China", "CN");
115 mapper.insertNamedBean(country1);
116 Country country2 = new Country("Canada", "CA");
117 mapper.insertNamedBean(country2);
118 sqlSession.flushStatements();
119 sqlSession.clearCache();
120 assertNotNull(country1.getId());
121 assertNotNull(country2.getId());
122 } finally {
123 sqlSession.rollback();
124 }
125 }
126 }
127
128 @Test
129 void shouldAssignKeyToNamedBean_keyPropertyWithParamName() {
130 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
131 try {
132 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
133 Country country = new Country("China", "CN");
134 mapper.insertNamedBean_keyPropertyWithParamName(country);
135 assertNotNull(country.getId());
136 } finally {
137 sqlSession.rollback();
138 }
139 }
140 }
141
142 @Test
143 void shouldAssignKeyToNamedBean_keyPropertyWithParamName_batch() {
144 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
145 try {
146 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
147 Country country1 = new Country("China", "CN");
148 mapper.insertNamedBean_keyPropertyWithParamName(country1);
149 Country country2 = new Country("Canada", "CA");
150 mapper.insertNamedBean_keyPropertyWithParamName(country2);
151 sqlSession.flushStatements();
152 sqlSession.clearCache();
153 assertNotNull(country1.getId());
154 assertNotNull(country2.getId());
155 } finally {
156 sqlSession.rollback();
157 }
158 }
159 }
160
161 @Test
162 void shouldAssignKeysToList() {
163 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
164 try {
165 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
166 List<Country> countries = new ArrayList<>();
167 countries.add(new Country("China", "CN"));
168 countries.add(new Country("United Kiongdom", "GB"));
169 countries.add(new Country("United States of America", "US"));
170 mapper.insertList(countries);
171 for (Country country : countries) {
172 assertNotNull(country.getId());
173 }
174 } finally {
175 sqlSession.rollback();
176 }
177 }
178 }
179
180 @Test
181 void shouldAssignKeysToNamedList() {
182 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
183 try {
184 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
185 List<Country> countries = new ArrayList<>();
186 countries.add(new Country("China", "CN"));
187 countries.add(new Country("United Kiongdom", "GB"));
188 countries.add(new Country("United States of America", "US"));
189 mapper.insertNamedList(countries);
190 for (Country country : countries) {
191 assertNotNull(country.getId());
192 }
193 } finally {
194 sqlSession.rollback();
195 }
196 }
197 }
198
199 @Test
200 void shouldAssingKeysToCollection() {
201 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
202 try {
203 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
204 Set<Country> countries = new HashSet<>();
205 countries.add(new Country("China", "CN"));
206 countries.add(new Country("United Kiongdom", "GB"));
207 mapper.insertSet(countries);
208 for (Country country : countries) {
209 assertNotNull(country.getId());
210 }
211 } finally {
212 sqlSession.rollback();
213 }
214 }
215 }
216
217 @Test
218 void shouldAssingKeysToNamedCollection() {
219 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
220 try {
221 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
222 Set<Country> countries = new HashSet<>();
223 countries.add(new Country("China", "CN"));
224 countries.add(new Country("United Kiongdom", "GB"));
225 mapper.insertNamedSet(countries);
226 for (Country country : countries) {
227 assertNotNull(country.getId());
228 }
229 } finally {
230 sqlSession.rollback();
231 }
232 }
233 }
234
235 @Test
236 void shouldAssingKeysToArray() {
237 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
238 try {
239 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
240 Country[] countries = new Country[2];
241 countries[0] = new Country("China", "CN");
242 countries[1] = new Country("United Kiongdom", "GB");
243 mapper.insertArray(countries);
244 for (Country country : countries) {
245 assertNotNull(country.getId());
246 }
247 } finally {
248 sqlSession.rollback();
249 }
250 }
251 }
252
253 @Test
254 void shouldAssingKeysToNamedArray() {
255 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
256 try {
257 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
258 Country[] countries = new Country[2];
259 countries[0] = new Country("China", "CN");
260 countries[1] = new Country("United Kiongdom", "GB");
261 mapper.insertNamedArray(countries);
262 for (Country country : countries) {
263 assertNotNull(country.getId());
264 }
265 } finally {
266 sqlSession.rollback();
267 }
268 }
269 }
270
271 @Test
272 void shouldAssignKeyToBean_MultiParams() {
273 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
274 try {
275 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
276 Country country = new Country("China", "CN");
277 mapper.insertMultiParams(country, 1);
278 assertNotNull(country.getId());
279 } finally {
280 sqlSession.rollback();
281 }
282 }
283 }
284
285 @Test
286 void shouldFailIfKeyPropertyIsInvalid_NoParamName() {
287 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
288 try {
289 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
290 Country country = new Country("China", "CN");
291 when(() -> mapper.insertMultiParams_keyPropertyWithoutParamName(country, 1));
292 then(caughtException()).isInstanceOf(PersistenceException.class).hasMessageContaining(
293 """
294 Could not determine which parameter to assign generated keys to. \
295 Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). \
296 Specified key properties are [id] and available parameters are [""");
297 } finally {
298 sqlSession.rollback();
299 }
300 }
301 }
302
303 @Test
304 void shouldFailIfKeyPropertyIsInvalid_WrongParamName() {
305 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
306 try {
307 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
308 Country country = new Country("China", "CN");
309 when(() -> mapper.insertMultiParams_keyPropertyWithWrongParamName(country, 1));
310 then(caughtException()).isInstanceOf(PersistenceException.class).hasMessageContaining(
311 """
312 Could not find parameter 'bogus'. \
313 Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). \
314 Specified key properties are [bogus.id] and available parameters are [""");
315 } finally {
316 sqlSession.rollback();
317 }
318 }
319 }
320
321 @Test
322 void shouldAssignKeysToNamedList_MultiParams() {
323 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
324 try {
325 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
326 List<Country> countries = new ArrayList<>();
327 countries.add(new Country("China", "CN"));
328 countries.add(new Country("United Kiongdom", "GB"));
329 mapper.insertList_MultiParams(countries, 1);
330 for (Country country : countries) {
331 assertNotNull(country.getId());
332 }
333 } finally {
334 sqlSession.rollback();
335 }
336 }
337 }
338
339 @Test
340 void shouldAssignKeysToNamedCollection_MultiParams() {
341 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
342 try {
343 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
344 Set<Country> countries = new HashSet<>();
345 countries.add(new Country("China", "CN"));
346 countries.add(new Country("United Kiongdom", "GB"));
347 mapper.insertSet_MultiParams(countries, 1);
348 for (Country country : countries) {
349 assertNotNull(country.getId());
350 }
351 } finally {
352 sqlSession.rollback();
353 }
354 }
355 }
356
357 @Test
358 void shouldAssignKeysToNamedArray_MultiParams() {
359 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
360 try {
361 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
362 Country[] countries = new Country[2];
363 countries[0] = new Country("China", "CN");
364 countries[1] = new Country("United Kiongdom", "GB");
365 mapper.insertArray_MultiParams(countries, 1);
366 for (Country country : countries) {
367 assertNotNull(country.getId());
368 }
369 } finally {
370 sqlSession.rollback();
371 }
372 }
373 }
374
375 @Test
376 void shouldAssignMultipleGeneratedKeysToABean() {
377 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
378 try {
379 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
380 Planet planet = new Planet();
381 planet.setName("pluto");
382 mapper.insertPlanet(planet);
383 assertEquals("pluto-" + planet.getId(), planet.getCode());
384 } finally {
385 sqlSession.rollback();
386 }
387 }
388 }
389
390 @Test
391 void shouldAssignMultipleGeneratedKeysToBeans() {
392 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
393 try {
394 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
395 Planet planet1 = new Planet();
396 planet1.setName("pluto");
397 Planet planet2 = new Planet();
398 planet2.setName("neptune");
399 List<Planet> planets = Arrays.asList(planet1, planet2);
400 mapper.insertPlanets(planets);
401 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
402 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
403 } finally {
404 sqlSession.rollback();
405 }
406 }
407 }
408
409 @Test
410 void shouldAssignMultipleGeneratedKeysToABean_MultiParams() {
411 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
412 try {
413 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
414 Planet planet = new Planet();
415 planet.setName("pluto");
416 mapper.insertPlanet_MultiParams(planet, 1);
417 assertEquals("pluto-" + planet.getId(), planet.getCode());
418 } finally {
419 sqlSession.rollback();
420 }
421 }
422 }
423
424 @Test
425 void shouldAssignMultipleGeneratedKeysToABean_MultiParams_batch() {
426 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
427 try {
428 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
429 Planet planet1 = new Planet();
430 planet1.setName("pluto");
431 mapper.insertPlanet_MultiParams(planet1, 1);
432 Planet planet2 = new Planet();
433 planet2.setName("neptune");
434 mapper.insertPlanet_MultiParams(planet2, 1);
435 sqlSession.flushStatements();
436 sqlSession.clearCache();
437 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
438 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
439 } finally {
440 sqlSession.rollback();
441 }
442 }
443 }
444
445 @Test
446 void shouldAssignMultipleGeneratedKeysToBeans_MultiParams() {
447 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
448 try {
449 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
450 Planet planet1 = new Planet();
451 planet1.setName("pluto");
452 Planet planet2 = new Planet();
453 planet2.setName("neptune");
454 List<Planet> planets = Arrays.asList(planet1, planet2);
455 mapper.insertPlanets_MultiParams(planets, 1);
456 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
457 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
458 } finally {
459 sqlSession.rollback();
460 }
461 }
462 }
463
464 @Test
465 void assigningMultipleKeysToDifferentParams() {
466 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
467 try {
468 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
469 Planet planet = new Planet();
470 planet.setName("pluto");
471 Map<String, Object> map = new HashMap<>();
472 mapper.insertAssignKeysToTwoParams(planet, map);
473 assertNotNull(planet.getId());
474 assertNotNull(map.get("code"));
475 } finally {
476 sqlSession.rollback();
477 }
478 }
479 }
480
481 @Test
482 void assigningMultipleKeysToDifferentParams_batch() {
483 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
484 try {
485 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
486 Planet planet1 = new Planet();
487 planet1.setName("pluto");
488 Map<String, Object> map1 = new HashMap<>();
489 mapper.insertAssignKeysToTwoParams(planet1, map1);
490 Planet planet2 = new Planet();
491 planet2.setName("pluto");
492 Map<String, Object> map2 = new HashMap<>();
493 mapper.insertAssignKeysToTwoParams(planet2, map2);
494 sqlSession.flushStatements();
495 sqlSession.clearCache();
496 assertNotNull(planet1.getId());
497 assertNotNull(map1.get("code"));
498 assertNotNull(planet2.getId());
499 assertNotNull(map2.get("code"));
500 } finally {
501 sqlSession.rollback();
502 }
503 }
504 }
505
506 @Test
507 void shouldErrorUndefineProperty() {
508 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
509 try {
510 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
511
512 when(() -> mapper.insertUndefineKeyProperty(new Country("China", "CN")));
513 then(caughtException()).isInstanceOf(PersistenceException.class).hasMessageContaining(
514 "### Error updating database. Cause: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty 'country_id' in 'org.apache.ibatis.submitted.keygen.Country'.");
515 } finally {
516 sqlSession.rollback();
517 }
518 }
519 }
520
521 @Test
522 void shouldFailIfTooManyGeneratedKeys() {
523 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
524 try {
525 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
526 when(() -> mapper.tooManyGeneratedKeys(new Country()));
527 then(caughtException()).isInstanceOf(PersistenceException.class)
528 .hasMessageContaining("Too many keys are generated. There are only 1 target objects.");
529 } finally {
530 sqlSession.rollback();
531 }
532 }
533 }
534
535 @Test
536 void shouldFailIfTooManyGeneratedKeys_ParamMap() {
537 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
538 try {
539 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
540 when(() -> mapper.tooManyGeneratedKeysParamMap(new Country(), 1));
541 then(caughtException()).isInstanceOf(PersistenceException.class)
542 .hasMessageContaining("Too many keys are generated. There are only 1 target objects.");
543 } finally {
544 sqlSession.rollback();
545 }
546 }
547 }
548
549 @Test
550 void shouldFailIfTooManyGeneratedKeys_Batch() {
551 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
552 try {
553 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
554 mapper.tooManyGeneratedKeysParamMap(new Country(), 1);
555 mapper.tooManyGeneratedKeysParamMap(new Country(), 1);
556 when(sqlSession::flushStatements);
557 then(caughtException()).isInstanceOf(PersistenceException.class)
558 .hasMessageContaining("Too many keys are generated. There are only 2 target objects.");
559 } finally {
560 sqlSession.rollback();
561 }
562 }
563 }
564
565 @Test
566 void shouldAssignKeysToListWithoutInvokingEqualsNorHashCode() {
567
568 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
569 try {
570 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
571 List<NpeCountry> countries = new ArrayList<>();
572 countries.add(new NpeCountry("China", "CN"));
573 countries.add(new NpeCountry("United Kiongdom", "GB"));
574 countries.add(new NpeCountry("United States of America", "US"));
575 mapper.insertWeirdCountries(countries);
576 for (NpeCountry country : countries) {
577 assertNotNull(country.getId());
578 }
579 } finally {
580 sqlSession.rollback();
581 }
582 }
583 }
584
585 @Test
586 void shouldAssignKeyToAParamWithTrickyName() {
587 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
588 try {
589 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
590 Country country = new Country("China", "CN");
591 mapper.singleParamWithATrickyName(country);
592 assertNotNull(country.getId());
593 } finally {
594 sqlSession.rollback();
595 }
596 }
597 }
598
599 @Test
600 void shouldAssingKeysToAMap() {
601 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
602 try {
603 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
604 Map<String, Object> map = new HashMap<>();
605 map.put("countrycode", "CN");
606 map.put("countryname", "China");
607 mapper.insertMap(map);
608 assertNotNull(map.get("id"));
609 } finally {
610 sqlSession.rollback();
611 }
612 }
613 }
614 }