Today I was preparing an example using Spring Boot and using MyBatis to link data access next to Spring-MyBatis. Here is the relevant project configuration (using maven):
src/main/java - edu.home.ltmj.controller + CategoryController.java - edu.home.ltmj.dao + CategoryDao.java - edu.home.ltmj.domain + Category.java src/main/resources - edu.home.ltmj.dao + CategoryMapper.xml
Relevant file contents:
CategoryDao.java:
package edu.home.ltmj.dao; public interface CategoryDao { List<Category> getAllCategories(); }
CategoryMapper.xml:
<mapper namespace="edu.home.ltmj.dao.CategoryDao"> <resultMap id="categoryMap" type="edu.home.ltmj.domain.Category"> <id property="id" column="id" /> <result property="name" column="name" /> </resultMap> <select id="getAllCategories" resultMap="categoryMap"> SELECT id, nombre FROM category </select> </mapper>
Then I insert an instance of this dao into the request controller (for testing purposes), for example:
package edu.home.ltmj.controller; @RestController public class CategoryController { @Autowired private CategoryDao dao; @RequestMapping(value="/category/all", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE) public List<Categoria> getAllCategories() { return dao.getAllCategories(); } }
I run my project and test execution with curl localhost:8080/category/all , and then expect to see the results in JSON format, but instead got this exception:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): edu.home.ltmj.dao.CategoryDao.getAllCategories at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189) at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43) at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51) at com.sun.proxy.$Proxy45.getAllCategories(Unknown Source) at edu.home.ltmj.controller.CategoryRestController.getAllCategories(CategoryRestController.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) (...)
I do not understand the reason for this. There is a CategoryDao interface and it has the correct getAllCategories method, which corresponds to <select id="getAllCategories"> . After some time playing with this, I changed the dao interface name to CategoryMapper and updated the namespace in CategoryMapper.xml. After I did this, everything worked fine . In addition, after the same name for the class and xml, I moved the dao and xml-mapper class to different packages (for example, using the same name for: CategoryMapper.), Updated the namespace in the XML file and received the same exception with an updated message to show the dao interface package name. But then again, I moved both files to the same package, and everything worked again.
So my question is: why does MyBatis need the interface and the xml mapper file to have the same name and be in the same package? Is this a MyBatis project or a problem in Spring MyBatis?