概要
MyBatis Generatorで生成したMapperを呼び出そうとしたところ、以下のようなエラーが出ました:
There was an unexpected error (type=Internal Server Error, status=500).
Invalid bound statement (not found): com.example.demo.dao.FileTypeMapper.selectByExample
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.demo.dao.FileTypeMapper.selectByExample
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
...
この記事では、このエラーが出る原因と解決方法について調べた結果を共有します。
原因
Mapperインターフェース(*Mapper.java
)とMapper XML(*Mapper.xml
)のクラスパスが一致していない場合に、上のようなエラーが出てしまうようです。
このことが公式ドキュメントに書かれていないか調べてみたのですが、以下のあたりが該当しているのでしょうか・・・(?)
http://mybatis.org/spring/mappers.html
If the UserMapper has a corresponding MyBatis XML mapper file in the same classpath location as the mapper interface, it will be parsed automatically by theMapperFactoryBean
. There is no need to specify the mapper in a MyBatis configuration file unless the mapper XML files are in a different classpath location.
自分の環境でエラーが出た原因ですが、MySQLで以下のようなデータベースを作成し・・・
CREATE TABLE DEMODB.FILE_TYPE (
TYPE_ID INT NOT NULL PRIMARY KEY,
NAME VARCHAR(256) NOT NULL
);
CREATE TABLE DEMODB.FILE (
TYPE_ID INT NOT NULL PRIMARY KEY,
NAME VARCHAR(256) NOT NULL,
CONTENT LONGBLOB NOT NULL
);
・・・そして、上のデータベースに対して、MyBatis GeneratorのgeneratorConfig.xml
を以下のように設定してMapperを生成していました。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<classPathEntry
location="C:\Users\hiroki\.m2\repository\com\mysql\mysql-connector-j\8.0.31\mysql-connector-j-8.0.31.jar" />
<context id="MySQLTables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/DEMODB" userId="dev"
password="password1234">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<javaModelGenerator
targetProject="mybatis-generator-example/src/main/java"
targetPackage="com.example.demo.model">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator
targetProject="mybatis-generator-example/src/main/resources"
targetPackage="xml">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetProject="mybatis-generator-example/src/main/java"
targetPackage="com.example.demo.dao">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table schema="DEMODB" tableName="FILE_TYPE">
<property name="useActualColumnNames" value="true" />
</table>
<table schema="DEMODB" tableName="FILE">
<property name="useActualColumnNames" value="true" />
</table>
</context>
</generatorConfiguration>
ここで、generatorConfig.xml
の中で
sqlMapGenerator.targetPackage="xml"
javaClientGenerator.targetPackage="com.example.demo.dao"
となっており、両者が一致していないため、エラーが出たようです。
解決方法
解決方法は2つあります。
-
generatorConfig.xml
でtargetPackage
の値を一致させる。 -
application.properties
でMapperの場所を明示的に指定する。
これらの方法をそれぞれ解説していきます。
1. generatorConfig.xml
でtargetPackage
の値を一致させる
以下のように、generatorConfig.xml
の中でsqlMapGenerator
とjavaClientGenerator
のtargetPackage
の値が一致するように修正します。
その後、再びMyBatis Generatorを実行してMapperを再生成すると、最初に載せたエラーが出なくなります。
具体的には、generatorConfig.xml
を以下のように修正します。
...
<sqlMapGenerator
targetProject="mybatis-generator-example/src/main/resources"
targetPackage="com.example.demo.dao"> <-- ここを一致させる
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetProject="mybatis-generator-example/src/main/java"
targetPackage="com.example.demo.dao"> <-- ここを一致させる
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
...
2. application.properties
でMapperの場所を明示的に指定する
generatorConfig.xml
で指定したsqlMapGenerator.targetPackage
の場所を、application.properties
のmybatis.mapper-locations
で指定します。
具体的には、以下のように設定します。
...
<sqlMapGenerator
targetProject="mybatis-generator-example/src/main/resources"
targetPackage="xml"> <-- このようにパスを指定した場合・・・
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetProject="mybatis-generator-example/src/main/java"
targetPackage="com.example.demo.dao">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
...
mybatis.mapper-locations:classpath*:xml/*.xml <-- このように記載する