View Javadoc
1   /*
2    *    Copyright 2009-2024 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    interface Mapper {
47      // @formatter:off
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      // @formatter:on
58      Author selectAuthor(int id);
59  
60      // @formatter:off
61      @Select({
62          "SELECT ",
63          "  ID,", // unknown property type
64          "  USERNAME",
65          "FROM AUTHOR WHERE ID = #{id}"
66        })
67      // @formatter:on
68      SimpleAuthor selectSimpleAuthor(int id);
69    }
70  
71    static class SimpleAuthor {
72      private AtomicInteger id; // unknown property type
73      private String username;
74  
75      public AtomicInteger getId() {
76        return id;
77      }
78  
79      public void setId(AtomicInteger id) {
80        this.id = id;
81      }
82  
83      public String getUsername() {
84        return username;
85      }
86  
87      public void setUsername(String username) {
88        this.username = username;
89      }
90    }
91  
92    public static class LastEventSavedAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
93      private static ILoggingEvent lastEvent;
94  
95      @Override
96      protected void append(ILoggingEvent event) {
97        lastEvent = event;
98      }
99    }
100 
101   private static SqlSessionFactory sqlSessionFactory;
102 
103   @BeforeAll
104   static void setup() throws Exception {
105     DataSource dataSource = BaseDataTest.createBlogDataSource();
106     TransactionFactory transactionFactory = new JdbcTransactionFactory();
107     Environment environment = new Environment("Production", transactionFactory, dataSource);
108     Configuration configuration = new Configuration(environment);
109     configuration.addMapper(Mapper.class);
110     sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
111   }
112 
113   @Test
114   void none() {
115     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.NONE);
116     try (SqlSession session = sqlSessionFactory.openSession()) {
117       Mapper mapper = session.getMapper(Mapper.class);
118       Author author = mapper.selectAuthor(101);
119       assertThat(author.getId()).isEqualTo(101);
120       assertThat(author.getUsername()).isNull();
121     }
122   }
123 
124   @Test
125   void warningCauseByUnknownPropertyType() {
126     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.WARNING);
127     try (SqlSession session = sqlSessionFactory.openSession()) {
128       Mapper mapper = session.getMapper(Mapper.class);
129       SimpleAuthor author = mapper.selectSimpleAuthor(101);
130       assertThat(author.getId()).isNull();
131       assertThat(author.getUsername()).isEqualTo("jim");
132       assertThat(LastEventSavedAppender.lastEvent.getMessage()).isEqualTo(
133           "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]");
134     }
135   }
136 
137   @Test
138   void failingCauseByUnknownColumn() {
139     sqlSessionFactory.getConfiguration().setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.FAILING);
140     try (SqlSession session = sqlSessionFactory.openSession()) {
141       Mapper mapper = session.getMapper(Mapper.class);
142       mapper.selectAuthor(101);
143     } catch (PersistenceException e) {
144       assertThat(e.getCause()).isInstanceOf(SqlSessionException.class);
145       assertThat(e.getCause().getMessage()).isEqualTo(
146           "Unknown column is detected on 'org.apache.ibatis.session.AutoMappingUnknownColumnBehaviorTest$Mapper.selectAuthor' auto-mapping. Mapping parameters are [columnName=USERNAMEEEE,propertyName=USERNAMEEEE,propertyType=null]");
147     }
148   }
149 
150 }