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