user2327348
user2327348

Reputation: 57

Spring + MyBatis exception: Mapped Statements collection does not contain value for

I got this exception when I executed this app:

public class MainApp {

    private static ApplicationContext context = null;
    static SqlSession session = null;

    public static void main(String[] args) throws IllegalArgumentException {
        try {

            context = new FileSystemXmlApplicationContext(
                                            "src/main/webapp/WEB-INF/applicationContext.xml");
            session = (SqlSession) context.getBean("sqlSession");
            OrderMapper orderMapper = session.getMapper(OrderMapper.class);
            int orderQuantity = orderMapper.getAllOrder().size();
            System.out.println("Order quantity: " + orderQuantity);
            session.commit();
            session.close();
        } catch (Throwable e) {
            e.printStackTrace();
        } 
    }
}

Here is my OrderMapper interface:

public interface OrderMapper {

    public List<Order> getAllOrder();
}

OrderMapper.xml

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.thonglm1.spring.mappers.OrderMapper">

    <resultMap id="result" type="order">
        <result property="orderId" column="cartid" />
        <result property="type" column="type" />
        <result property="saleId" column="saleId" />
        <result property="status" column="status" />
        <result property="info1" column="info1" />
        <result property="info2" column="info2" />
        <result property="info3" column="info3" />
    </resultMap>

    <select id="getAllOrder" resultMap="result">
        select cartId, type,
        info1
        from TRAIN_ORDER;
    </select>
</mapper>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@172.21.8.62:1521:SHESVDEV" />
        <property name="username" value="test" />
        <property name="password" value="test" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="src/main/webapp/WEB-INF/mybatis-config.xml" />
    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.thonglm1.spring.mappers" />
    </bean>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

mybatis-config.xml

?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias type="com.thonglm1.spring.domain.Order" alias="order" />
    </typeAliases>
    <mappers>
        <package name="com.thonglm1.spring.mappers" />
    </mappers>
</configuration>

And finally, the exception I got:

java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.thonglm1.spring.mappers.OrderMapper.getAllOrder at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:672) at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:507) at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:500) at org.apache.ibatis.binding.MapperMethod.setupCommandType(MapperMethod.java:240) at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:71) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:39) at $Proxy6.getAllOrder(Unknown Source) at MainApp.main(MainApp.java:21)

And 1 more thing, since I quite new to this, is there any bad practices in my code ? Or anything I could improve ? Please feel free to comment, I'd really appreciate it.

Upvotes: 2

Views: 24496

Answers (2)

Karthik Prasad
Karthik Prasad

Reputation: 10034

Where have you specified the mapper XML location? You could add it in sqlSessionFactory's property mapperLocations. Since you are using maven. I believe it is better to move the mapper XML file to a folder inside resources directory. When You add more number of XML files it will be easier to maintain. I think the below folder structure would make sense as all the related stuff are grouped together with all your JDBC related stuff under one package with subpackages as domain, mappers, service interfaces and service interface implementation.

enter image description here

In this case since all the configurations go inside WEB-INF/classes directory during compile/packaging, which is also a classpath, this application configuration should hold good.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@172.21.8.62:1521:SHESVDEV" />
        <property name="username" value="test" />
        <property name="password" value="test" />
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
       <property name="configLocation" value="classpath:config/mybatis-config.xml" />
    <property name="mapperLocations" value="classpath*:sqlmap/*.xml" />
    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.thonglm1.spring.mappers" />
    </bean>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

And the mybatis-config.xml, by default all the aliases in the domain package will be class name with the first letter being smaller.

?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <typeAliases>
        <package name="com.thonglm1.spring.domain" />
    </typeAliases>       
</configuration>

Upvotes: 2

jorrin
jorrin

Reputation: 512

If the package cannot be read you can try adding the resource directly:

?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias type="com.thonglm1.spring.domain.Order" alias="order" />
    </typeAliases>
    <mappers>
        <mapper resource="folderWhereIsXMLMapperIssaved/orderMapper.xml" />
    </mappers>
</configuration>

Upvotes: 0

Related Questions