【問題解決】MyBatisのMapperクラスでオーバロードが使えない


# 環境
* mybatis-spring-boot-starter: 1.3.1
    - mybatis: 3.4.5
* Spring Boot 1.5.9
* Java8


# 問題

MyBatisのMapperクラスに、オーバロードしてメソッドを定義しました。

```java:CityMapper.java
@Mapper
public interface CityMapper {

	@Select("select * from city where state = #{state}")
	City findCity(@Param("state") String state);

	@Select("select * from city")
	City findCity();

}
```

サーバを起動すると、「Mapped Statements collection already contains value for ～findByState」というエラーが発生しました。

```txt:console
2018-01-22 23:55:31.816 ERROR 24176 --- [  restartedMain] o.m.spring.mapper.MapperFactoryBean      : Error while adding the mapper 'interface com.example.demo2.mapper.CityMapper' to configuration.

java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.example.demo2.mapper.CityMapper.findCity
	at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:872) ~[mybatis-3.4.5.jar:3.4.5]
```


# 原因・解決策
「`findByState`が既に含まれている」というエラーメッセージなので、メソッド名を重複しないような名前に変更して、解決しました。

```java:CityMapper.java
@Mapper
public interface CityMapper {

	@Select("select * from city where state = #{state}")
	City findCityByState(@Param("state") String state);

	@Select("select * from city")
	City findCity();

}
```

## 同様の問題

XMLファイルでidが重複しているときも、「Mapped Statements collection already contains value for ～」という同様のエラーが発生します。

```xml:HotelMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo2.mybatis.mapper.HotelMapper">

    <select id="findHotel" resultType="com.example.demo2.mybatis.domain.Hotel">
        select * from hotel where city = #{id}
    </select>

    <!-- id名が重複している -->
    <select id="findHotel" resultType="com.example.demo2.mybatis.domain.Hotel">
        select * from hotel
    </select>

</mapper>
```

```txt:console
2018-01-23 00:51:47.444 ERROR 14712 --- [  restartedMain] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'hotelDao' defined in file [C:\MyProgram\pleiades_4.7\workspace\demo2\target\classes\com\example\demo2\mybatis\dao\HotelDao.class]: 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'sqlSessionTemplate' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: 
Unsatisfied dependency expressed through method 'sqlSessionTemplate' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: 
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: 
Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: 
Failed to parse config resource: class path resource [mybatis-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: 
Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: 
Mapped Statements collection already contains value for com.example.demo2.mybatis.mapper.HotelMapper.findHotel
...
Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.example.demo2.mybatis.mapper.HotelMapper.findHotel
```

※読みやすくするために、適当な箇所で改行を入れました。



# 参考にしたサイト
* [【メモ】MyBatisのMapperでオーバーロードをしてはいけない](http://hsuzuki.hatenablog.com/entry/2016/09/02/140758)
* [not support overload?](https://github.com/mybatis/mybatis-3/issues/511)
* [MyBatisエラー別対応とか](http://nantonaku-shiawase.hatenablog.com/entry/2017/07/12/001747)