読者です 読者をやめる 読者になる 読者になる

mybatis RowBounds NullPointerException

範囲指定のクエリ、いわゆる offset-Limit のクエリ、
Sqlsession の 
select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)

を使っていたら、
システム起動してから最初の実行だけ、NullPointerException が発生した。

どうやら、以下のスタックトレースから、、
Caused by: java.lang.NullPointerException
   at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:269)
   at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
   at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
   at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
   at org.apache.ibatis.session.defaults.DefaultSqlSession.select(DefaultSqlSession.java:128)

以下を見つけた。

https://github.com/mybatis/mybatis-3/issues/72

どうやら、デフォルト時のキャッシュの操作が良くないみたいだ。
思いきって Ehcache を使うことにしたら解決した。
いや、やっぱりダメである。

Maven mybatis-ehcache JAR を持ってくる。

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.3</version>
</dependency>

Configuration.xml に、cacheEnabled = true を設定

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "">http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
  <settings>
     <setting name="cacheEnabled" value="true"/>
  </settings>

  <environments default="development">
      <environment id="development">
           <transactionManager type="JDBC"/>
              <dataSource type="JNDI">
                 <property name="data_source" value="java:comp/env/jdbc/sampledb"/>
              </dataSource>
       </environment>
   </environments>
   <mappers>
      <mapper resource="sqlmap.xml"/>
   </mappers>
</configuration>

sqlmap.xml に、使用する cache を指定する。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "">http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="org.sample.MyMapper">

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

<select 
   :
</select>

</mapper>

BaseExecutorqueryFromDatabase で、NullPointerException が発生したら、
このように、キャッシュを使うという解決方法を覚えておくと良いかもしれない。