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)
293 .hasMessageContaining("Could not determine which parameter to assign generated keys to. "
294 + "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
295 + "Specified key properties are [id] and available parameters are [");
296 } finally {
297 sqlSession.rollback();
298 }
299 }
300 }
301
302 @Test
303 void shouldFailIfKeyPropertyIsInvalid_WrongParamName() {
304 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
305 try {
306 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
307 Country country = new Country("China", "CN");
308 when(() -> mapper.insertMultiParams_keyPropertyWithWrongParamName(country, 1));
309 then(caughtException()).isInstanceOf(PersistenceException.class)
310 .hasMessageContaining("Could not find parameter 'bogus'. "
311 + "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
312 + "Specified key properties are [bogus.id] and available parameters are [");
313 } finally {
314 sqlSession.rollback();
315 }
316 }
317 }
318
319 @Test
320 void shouldAssignKeysToNamedList_MultiParams() {
321 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
322 try {
323 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
324 List<Country> countries = new ArrayList<>();
325 countries.add(new Country("China", "CN"));
326 countries.add(new Country("United Kiongdom", "GB"));
327 mapper.insertList_MultiParams(countries, 1);
328 for (Country country : countries) {
329 assertNotNull(country.getId());
330 }
331 } finally {
332 sqlSession.rollback();
333 }
334 }
335 }
336
337 @Test
338 void shouldAssignKeysToNamedCollection_MultiParams() {
339 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
340 try {
341 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
342 Set<Country> countries = new HashSet<>();
343 countries.add(new Country("China", "CN"));
344 countries.add(new Country("United Kiongdom", "GB"));
345 mapper.insertSet_MultiParams(countries, 1);
346 for (Country country : countries) {
347 assertNotNull(country.getId());
348 }
349 } finally {
350 sqlSession.rollback();
351 }
352 }
353 }
354
355 @Test
356 void shouldAssignKeysToNamedArray_MultiParams() {
357 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
358 try {
359 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
360 Country[] countries = new Country[2];
361 countries[0] = new Country("China", "CN");
362 countries[1] = new Country("United Kiongdom", "GB");
363 mapper.insertArray_MultiParams(countries, 1);
364 for (Country country : countries) {
365 assertNotNull(country.getId());
366 }
367 } finally {
368 sqlSession.rollback();
369 }
370 }
371 }
372
373 @Test
374 void shouldAssignMultipleGeneratedKeysToABean() {
375 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
376 try {
377 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
378 Planet planet = new Planet();
379 planet.setName("pluto");
380 mapper.insertPlanet(planet);
381 assertEquals("pluto-" + planet.getId(), planet.getCode());
382 } finally {
383 sqlSession.rollback();
384 }
385 }
386 }
387
388 @Test
389 void shouldAssignMultipleGeneratedKeysToBeans() {
390 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
391 try {
392 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
393 Planet planet1 = new Planet();
394 planet1.setName("pluto");
395 Planet planet2 = new Planet();
396 planet2.setName("neptune");
397 List<Planet> planets = Arrays.asList(planet1, planet2);
398 mapper.insertPlanets(planets);
399 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
400 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
401 } finally {
402 sqlSession.rollback();
403 }
404 }
405 }
406
407 @Test
408 void shouldAssignMultipleGeneratedKeysToABean_MultiParams() {
409 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
410 try {
411 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
412 Planet planet = new Planet();
413 planet.setName("pluto");
414 mapper.insertPlanet_MultiParams(planet, 1);
415 assertEquals("pluto-" + planet.getId(), planet.getCode());
416 } finally {
417 sqlSession.rollback();
418 }
419 }
420 }
421
422 @Test
423 void shouldAssignMultipleGeneratedKeysToABean_MultiParams_batch() {
424 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
425 try {
426 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
427 Planet planet1 = new Planet();
428 planet1.setName("pluto");
429 mapper.insertPlanet_MultiParams(planet1, 1);
430 Planet planet2 = new Planet();
431 planet2.setName("neptune");
432 mapper.insertPlanet_MultiParams(planet2, 1);
433 sqlSession.flushStatements();
434 sqlSession.clearCache();
435 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
436 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
437 } finally {
438 sqlSession.rollback();
439 }
440 }
441 }
442
443 @Test
444 void shouldAssignMultipleGeneratedKeysToBeans_MultiParams() {
445 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
446 try {
447 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
448 Planet planet1 = new Planet();
449 planet1.setName("pluto");
450 Planet planet2 = new Planet();
451 planet2.setName("neptune");
452 List<Planet> planets = Arrays.asList(planet1, planet2);
453 mapper.insertPlanets_MultiParams(planets, 1);
454 assertEquals("pluto-" + planet1.getId(), planet1.getCode());
455 assertEquals("neptune-" + planet2.getId(), planet2.getCode());
456 } finally {
457 sqlSession.rollback();
458 }
459 }
460 }
461
462 @Test
463 void assigningMultipleKeysToDifferentParams() {
464 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
465 try {
466 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
467 Planet planet = new Planet();
468 planet.setName("pluto");
469 Map<String, Object> map = new HashMap<>();
470 mapper.insertAssignKeysToTwoParams(planet, map);
471 assertNotNull(planet.getId());
472 assertNotNull(map.get("code"));
473 } finally {
474 sqlSession.rollback();
475 }
476 }
477 }
478
479 @Test
480 void assigningMultipleKeysToDifferentParams_batch() {
481 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
482 try {
483 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
484 Planet planet1 = new Planet();
485 planet1.setName("pluto");
486 Map<String, Object> map1 = new HashMap<>();
487 mapper.insertAssignKeysToTwoParams(planet1, map1);
488 Planet planet2 = new Planet();
489 planet2.setName("pluto");
490 Map<String, Object> map2 = new HashMap<>();
491 mapper.insertAssignKeysToTwoParams(planet2, map2);
492 sqlSession.flushStatements();
493 sqlSession.clearCache();
494 assertNotNull(planet1.getId());
495 assertNotNull(map1.get("code"));
496 assertNotNull(planet2.getId());
497 assertNotNull(map2.get("code"));
498 } finally {
499 sqlSession.rollback();
500 }
501 }
502 }
503
504 @Test
505 void shouldErrorUndefineProperty() {
506 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
507 try {
508 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
509
510 when(() -> mapper.insertUndefineKeyProperty(new Country("China", "CN")));
511 then(caughtException()).isInstanceOf(PersistenceException.class).hasMessageContaining(
512 "### 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'.");
513 } finally {
514 sqlSession.rollback();
515 }
516 }
517 }
518
519 @Test
520 void shouldFailIfTooManyGeneratedKeys() {
521 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
522 try {
523 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
524 when(() -> mapper.tooManyGeneratedKeys(new Country()));
525 then(caughtException()).isInstanceOf(PersistenceException.class)
526 .hasMessageContaining("Too many keys are generated. There are only 1 target objects.");
527 } finally {
528 sqlSession.rollback();
529 }
530 }
531 }
532
533 @Test
534 void shouldFailIfTooManyGeneratedKeys_ParamMap() {
535 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
536 try {
537 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
538 when(() -> mapper.tooManyGeneratedKeysParamMap(new Country(), 1));
539 then(caughtException()).isInstanceOf(PersistenceException.class)
540 .hasMessageContaining("Too many keys are generated. There are only 1 target objects.");
541 } finally {
542 sqlSession.rollback();
543 }
544 }
545 }
546
547 @Test
548 void shouldFailIfTooManyGeneratedKeys_Batch() {
549 try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
550 try {
551 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
552 mapper.tooManyGeneratedKeysParamMap(new Country(), 1);
553 mapper.tooManyGeneratedKeysParamMap(new Country(), 1);
554 when(sqlSession::flushStatements);
555 then(caughtException()).isInstanceOf(PersistenceException.class)
556 .hasMessageContaining("Too many keys are generated. There are only 2 target objects.");
557 } finally {
558 sqlSession.rollback();
559 }
560 }
561 }
562
563 @Test
564 void shouldAssignKeysToListWithoutInvokingEqualsNorHashCode() {
565
566 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
567 try {
568 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
569 List<NpeCountry> countries = new ArrayList<>();
570 countries.add(new NpeCountry("China", "CN"));
571 countries.add(new NpeCountry("United Kiongdom", "GB"));
572 countries.add(new NpeCountry("United States of America", "US"));
573 mapper.insertWeirdCountries(countries);
574 for (NpeCountry country : countries) {
575 assertNotNull(country.getId());
576 }
577 } finally {
578 sqlSession.rollback();
579 }
580 }
581 }
582
583 @Test
584 void shouldAssignKeyToAParamWithTrickyName() {
585 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
586 try {
587 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
588 Country country = new Country("China", "CN");
589 mapper.singleParamWithATrickyName(country);
590 assertNotNull(country.getId());
591 } finally {
592 sqlSession.rollback();
593 }
594 }
595 }
596
597 @Test
598 void shouldAssingKeysToAMap() {
599 try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
600 try {
601 CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
602 Map<String, Object> map = new HashMap<>();
603 map.put("countrycode", "CN");
604 map.put("countryname", "China");
605 mapper.insertMap(map);
606 assertNotNull(map.get("id"));
607 } finally {
608 sqlSession.rollback();
609 }
610 }
611 }
612 }