View Javadoc
1   /*
2    *    Copyright 2009-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.submitted.nestedresulthandler;
17  
18  import java.io.Reader;
19  import java.util.List;
20  
21  import org.apache.ibatis.BaseDataTest;
22  import org.apache.ibatis.exceptions.PersistenceException;
23  import org.apache.ibatis.io.Resources;
24  import org.apache.ibatis.session.SqlSession;
25  import org.apache.ibatis.session.SqlSessionFactory;
26  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
27  import org.junit.jupiter.api.Assertions;
28  import org.junit.jupiter.api.BeforeAll;
29  import org.junit.jupiter.api.Test;
30  
31  class NestedResultHandlerTest {
32    private static SqlSessionFactory sqlSessionFactory;
33  
34    @BeforeAll
35    static void setUp() throws Exception {
36      // create a SqlSessionFactory
37      try (Reader reader = Resources
38          .getResourceAsReader("org/apache/ibatis/submitted/nestedresulthandler/mybatis-config.xml")) {
39        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
40      }
41  
42      // populate in-memory database
43      BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
44          "org/apache/ibatis/submitted/nestedresulthandler/CreateDB.sql");
45    }
46  
47    @Test
48    void testGetPerson() {
49      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
50        Mapper mapper = sqlSession.getMapper(Mapper.class);
51  
52        List<Person> persons = mapper.getPersons();
53  
54        Person person = persons.get(0);
55        Assertions.assertEquals("grandma", person.getName());
56        Assertions.assertTrue(person.owns("book"));
57        Assertions.assertTrue(person.owns("tv"));
58        Assertions.assertEquals(2, person.getItems().size());
59  
60        person = persons.get(1);
61        Assertions.assertEquals("sister", person.getName());
62        Assertions.assertTrue(person.owns("phone"));
63        Assertions.assertTrue(person.owns("shoes"));
64        Assertions.assertEquals(2, person.getItems().size());
65  
66        person = persons.get(2);
67        Assertions.assertEquals("brother", person.getName());
68        Assertions.assertTrue(person.owns("car"));
69        Assertions.assertEquals(1, person.getItems().size());
70      }
71    }
72  
73    @Test
74    // issue #542
75    void testGetPersonWithHandler() {
76      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
77        sqlSession.select("getPersons", context -> {
78          Person person = (Person) context.getResultObject();
79          if ("grandma".equals(person.getName())) {
80            Assertions.assertEquals(2, person.getItems().size());
81          }
82        });
83      }
84    }
85  
86    @Test
87    void testUnorderedGetPersonWithHandler() {
88      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
89        Assertions.assertThrows(PersistenceException.class,
90            () -> sqlSession.select("getPersonsWithItemsOrdered", context -> {
91              Person person = (Person) context.getResultObject();
92              if ("grandma".equals(person.getName())) {
93                person.getItems().size();
94              }
95            }));
96      }
97    }
98  
99    /**
100    * Fix bug caused by issue #542, see new issue #22 on github If we order by a nested result map attribute we can miss
101    * some records and end up with duplicates instead.
102    */
103   @Test
104   void testGetPersonOrderedByItem() {
105     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
106       Mapper mapper = sqlSession.getMapper(Mapper.class);
107 
108       List<Person> persons = mapper.getPersonsWithItemsOrdered();
109 
110       Person person = persons.get(0);
111       Assertions.assertEquals("grandma", person.getName());
112       Assertions.assertTrue(person.owns("book"));
113       Assertions.assertTrue(person.owns("tv"));
114       Assertions.assertEquals(2, person.getItems().size());
115 
116       person = persons.get(1);
117       Assertions.assertEquals("brother", person.getName());
118       Assertions.assertTrue(person.owns("car"));
119       Assertions.assertEquals(1, person.getItems().size());
120 
121       person = persons.get(2);
122       Assertions.assertEquals("sister", person.getName());
123       Assertions.assertTrue(person.owns("phone"));
124       Assertions.assertTrue(person.owns("shoes"));
125       Assertions.assertEquals(2, person.getItems().size());
126     }
127   }
128 
129   @Test // reopen issue 39? (not a bug?)
130   void testGetPersonItemPairs() {
131     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
132       Mapper mapper = sqlSession.getMapper(Mapper.class);
133       List<PersonItemPair> pairs = mapper.getPersonItemPairs();
134 
135       Assertions.assertNotNull(pairs);
136       // System.out.println( new StringBuilder().append("selected pairs: ").append(pairs) );
137 
138       Assertions.assertEquals(5, pairs.size());
139       Assertions.assertNotNull(pairs.get(0).getPerson());
140       Assertions.assertEquals(pairs.get(0).getPerson().getId(), Integer.valueOf(1));
141       Assertions.assertNotNull(pairs.get(0).getItem());
142       Assertions.assertEquals(pairs.get(0).getItem().getId(), Integer.valueOf(1));
143     }
144   }
145 
146 }