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.session;
17  
18  import static org.assertj.core.api.Assertions.assertThat;
19  
20  import ch.qos.logback.classic.spi.ILoggingEvent;
21  import ch.qos.logback.core.UnsynchronizedAppenderBase;
22  
23  import java.util.concurrent.atomic.AtomicInteger;
24  
25  import javax.sql.DataSource;
26  
27  import org.apache.ibatis.BaseDataTest;
28  import org.apache.ibatis.annotations.Select;
29  import org.apache.ibatis.domain.blog.Author;
30  import org.apache.ibatis.exceptions.PersistenceException;
31  import org.apache.ibatis.mapping.Environment;
32  import org.apache.ibatis.transaction.TransactionFactory;
33  import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
34  import org.junit.jupiter.api.BeforeAll;
35  import org.junit.jupiter.api.Test;
36  
37  /**
38   * Tests for specify the behavior when detects an unknown column (or unknown property type) of automatic mapping target.
39   *
40   * @since 3.4.0
41   *
42   * @author Kazuki Shimizu
43   */
44  class AutoMappingUnknownColumnBehaviorTest {
45  
46    // @formatter:off
47    interface Mapper {
48      @Select({
49          "SELECT ",
50          "  ID,",
51          "  USERNAME as USERNAMEEEE,", // unknown column
52          "  PASSWORD,",
53          "  EMAIL,",
54          "  BIO",
55          "FROM AUTHOR WHERE ID = #{id}"
56        })
57      Author selectAuthor(int id);
58  
59      @Select({
60          "SELECT ",
61          "  ID,", // unknown property type
62          "  USERNAME",
63          "FROM AUTHOR WHERE ID = #{id}"
64        })
65      SimpleAuthor selectSimpleAuthor(int id);
66    }
67    // @formatter:on
68  
69    static class SimpleAuthor {
70      private AtomicInteger id; // unknown property type
71      private String username;
72  
73      public AtomicInteger getId() {
74        return id;
75      }
76  
77      public void setId(AtomicInteger id) {
78        this.id = id;
79      }
80  
81      public String getUsername() {
82        return username;
83      }
84  
85      public void setUsername(String username) {
86        this.username = username;
87      }
88    }
89  
90    public static class LastEventSavedAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
91      private static ILoggingEvent lastEvent;
92  
93      @Override
94      protected void append(ILoggingEvent event) {
95        lastEvent = event;
96      }
97    }
98  
99    private static SqlSessionFactory sqlSessionFactory;
100 
101   @BeforeAll
102   static void setup() throws Exception {
103     DataSource dataSource = BaseDataTest.createBlogDataSource();
104     TransactionFactory transactionFactory = new JdbcTransactionFactory();
105     Environment environment = new Environment("Production", transactionFactory, dataSource);
106     Configuration configuration = new Configuration(environment);
107     configuration.addMapper(Mapper.class);
108     sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
109   }
110 
111   @Test
112   void none() {
113     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.NONE);
114     try (SqlSession session = sqlSessionFactory.openSession()) {
115       Mapper mapper = session.getMapper(Mapper.class);
116       Author author = mapper.selectAuthor(101);
117       assertThat(author.getId()).isEqualTo(101);
118       assertThat(author.getUsername()).isNull();
119     }
120   }
121 
122   @Test
123   void warningCauseByUnknownPropertyType() {
124     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.WARNING);
125     try (SqlSession session = sqlSessionFactory.openSession()) {
126       Mapper mapper = session.getMapper(Mapper.class);
127       SimpleAuthor author = mapper.selectSimpleAuthor(101);
128       assertThat(author.getId()).isNull();
129       assertThat(author.getUsername()).isEqualTo("jim");
130       assertThat(LastEventSavedAppender.lastEvent.getMessage()).isEqualTo(
131           "Unknown column is detected on 'org.apache.ibatis.session.AutoMappingUnknownColumnBehaviorTest$Mapper.selectSimpleAuthor' auto-mapping. Mapping parameters are [columnName=ID,propertyName=id,propertyType=java.util.concurrent.atomic.AtomicInteger]");
132     }
133   }
134 
135   @Test
136   void failingCauseByUnknownColumn() {
137     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.FAILING);
138     try (SqlSession session = sqlSessionFactory.openSession()) {
139       Mapper mapper = session.getMapper(Mapper.class);
140       mapper.selectAuthor(101);
141     } catch (PersistenceException e) {
142       assertThat(e.getCause()).isInstanceOf(SqlSessionException.class);
143       assertThat(e.getCause().getMessage()).isEqualTo(
144           "Unknown column is detected on 'org.apache.ibatis.session.AutoMappingUnknownColumnBehaviorTest$Mapper.selectAuthor' auto-mapping. Mapping parameters are [columnName=USERNAMEEEE,propertyName=USERNAMEEEE,propertyType=null]");
145     }
146   }
147 
148 }