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.lazy_properties;
17  
18  import static org.junit.jupiter.api.Assertions.assertEquals;
19  import static org.junit.jupiter.api.Assertions.assertNotNull;
20  
21  import java.io.Reader;
22  import java.util.Collections;
23  import java.util.HashSet;
24  
25  import org.apache.ibatis.BaseDataTest;
26  import org.apache.ibatis.executor.loader.ProxyFactory;
27  import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory;
28  import org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory;
29  import org.apache.ibatis.io.Resources;
30  import org.apache.ibatis.session.Configuration;
31  import org.apache.ibatis.session.SqlSession;
32  import org.apache.ibatis.session.SqlSessionFactory;
33  import org.apache.ibatis.session.SqlSessionFactoryBuilder;
34  import org.junit.jupiter.api.BeforeEach;
35  import org.junit.jupiter.api.Tag;
36  import org.junit.jupiter.api.Test;
37  
38  class LazyPropertiesTest {
39  
40    private static SqlSessionFactory sqlSessionFactory;
41  
42    @BeforeEach
43    void setUp() throws Exception {
44      // create an SqlSessionFactory
45      try (Reader reader = Resources
46          .getResourceAsReader("org/apache/ibatis/submitted/lazy_properties/mybatis-config.xml")) {
47        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
48      }
49  
50      // populate in-memory database
51      BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
52          "org/apache/ibatis/submitted/lazy_properties/CreateDB.sql");
53    }
54  
55    @Test
56    void shouldLoadOnlyTheInvokedLazyProperty() {
57      sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(false);
58      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
59        Mapper mapper = sqlSession.getMapper(Mapper.class);
60        User user = mapper.getUser(1);
61        assertEquals(0, user.setterCounter);
62        assertNotNull(user.getLazy1());
63        assertEquals(1, user.setterCounter, "Should NOT load other lazy properties.");
64      }
65    }
66  
67    @Test
68    void verifyAggressiveLazyLoadingBehavior() {
69      sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(true);
70      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
71        Mapper mapper = sqlSession.getMapper(Mapper.class);
72        User user = mapper.getUser(1);
73        // Setter invocation by MyBatis triggers aggressive lazy-loading.
74        assertEquals(3, user.setterCounter, "Should load all lazy properties.");
75      }
76    }
77  
78    @Test
79    void shouldToStringTriggerLazyLoading() {
80      sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(false);
81      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
82        Mapper mapper = sqlSession.getMapper(Mapper.class);
83        User user = mapper.getUser(1);
84        user.toString();
85        assertEquals(3, user.setterCounter);
86      }
87    }
88  
89    @Test
90    void shouldHashCodeTriggerLazyLoading() {
91      sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(false);
92      try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
93        Mapper mapper = sqlSession.getMapper(Mapper.class);
94        User user = mapper.getUser(1);
95        user.hashCode();
96        assertEquals(3, user.setterCounter);
97      }
98    }
99  
100   @Test
101   void shouldEqualsTriggerLazyLoading() {
102     sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(false);
103     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
104       Mapper mapper = sqlSession.getMapper(Mapper.class);
105       User user = mapper.getUser(1);
106       user.equals(null);
107       assertEquals(3, user.setterCounter);
108     }
109   }
110 
111   @Test
112   void shouldCloneTriggerLazyLoading() {
113     sqlSessionFactory.getConfiguration().setAggressiveLazyLoading(false);
114     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
115       Mapper mapper = sqlSession.getMapper(Mapper.class);
116       User user = mapper.getUser(1);
117       user.clone();
118       assertEquals(3, user.setterCounter);
119     }
120   }
121 
122   @Test
123   void verifyEmptyLazyLoadTriggerMethods() {
124     Configuration configuration = sqlSessionFactory.getConfiguration();
125     configuration.setAggressiveLazyLoading(false);
126     configuration.setLazyLoadTriggerMethods(new HashSet<>());
127     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
128       Mapper mapper = sqlSession.getMapper(Mapper.class);
129       User user = mapper.getUser(1);
130       user.toString();
131       user.hashCode();
132       user.equals(null);
133       user.clone();
134       assertEquals(0, user.setterCounter);
135     }
136   }
137 
138   @Test
139   void verifyCustomLazyLoadTriggerMethods() {
140     Configuration configuration = sqlSessionFactory.getConfiguration();
141     configuration.setAggressiveLazyLoading(false);
142     configuration.setLazyLoadTriggerMethods(new HashSet<>(Collections.singleton("trigger")));
143     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
144       Mapper mapper = sqlSession.getMapper(Mapper.class);
145       User user = mapper.getUser(1);
146       user.toString();
147       user.hashCode();
148       user.equals(null);
149       user.clone();
150       assertEquals(0, user.setterCounter);
151       user.trigger();
152       assertEquals(3, user.setterCounter);
153     }
154   }
155 
156   @Test
157   void shouldInvokingSetterInvalidateLazyLoading_Javassist() {
158     shoulInvokingSetterInvalidateLazyLoading(new JavassistProxyFactory());
159   }
160 
161   @Tag("RequireIllegalAccess")
162   @Test
163   void shouldInvokingSetterInvalidateLazyLoading_Cglib() {
164     shoulInvokingSetterInvalidateLazyLoading(new CglibProxyFactory());
165   }
166 
167   private void shoulInvokingSetterInvalidateLazyLoading(ProxyFactory proxyFactory) {
168     Configuration config = sqlSessionFactory.getConfiguration();
169     config.setProxyFactory(proxyFactory);
170     config.setAggressiveLazyLoading(false);
171     try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
172       Mapper mapper = sqlSession.getMapper(Mapper.class);
173       User user = mapper.getUser(1);
174       User u2 = new User();
175       u2.setId(99);
176       user.setLazy1(u2);
177       assertEquals(1, user.setterCounter);
178       assertEquals(Integer.valueOf(99), user.getLazy1().getId());
179       assertEquals(1, user.setterCounter);
180     }
181   }
182 }