SqlMapDaoTemplate migration from iBatis 2

282 views
Skip to first unread message

byteworks

unread,
Feb 16, 2012, 5:47:46 PM2/16/12
to mybati...@googlegroups.com
Upgrading a legacy Spring 2.5.6/iBatis 2 project to Spring 3.0.5/mybatis. I
would like to convert my existing DaoImpls as is, rather that migrating all
the SQL to mapper interfaces. Can somebody point to to an example Spring
configuration and dao impl? I injected the wrong mybatis bean initially (sql
session). Everything I've seen involved annotations on mappers, but I'm not
ready to do that work yet. I just want to finish the migration following a
best-practice incremental step. The Dao Impl configuration is the last TODO
left.

--
View this message in context: http://mybatis-user.963551.n3.nabble.com/SqlMapDaoTemplate-migration-from-iBatis-2-tp3752179p3752179.html
Sent from the mybatis-user mailing list archive at Nabble.com.

byteworks

unread,
Feb 16, 2012, 7:59:10 PM2/16/12
to mybati...@googlegroups.com
Specifically, the examples use something like this for annotated mapper
interface.

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface"
value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

I'm using an implementation of a dao converted from iBatis 2, to which I've
added a SqlSession. I realize this should probably be factory:

<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:com/something/core/dao/sqlMapConfig.xml"/>
</bean>

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

<bean id="someModelDao"
class="com.something.core.dao.impl.SomeModelDaoImpl"
p:sqlSession-ref="sqlSession" />

The called sql is straight forward:

<mapper namespace="com.something.core.dao.SomeModelDao">
<select id="findBySomething" resultMap="get-Result">
SELECT...

I get the following error:

org.mybatis.spring.MyBatisSystemException: nested exception is
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException:
null source
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: java.lang.IllegalArgumentException: null source

This happens on all the DAOs, so something is fundamentally wrong with my
converted implementation


--
View this message in context: http://mybatis-user.963551.n3.nabble.com/SqlMapDaoTemplate-migration-from-iBatis-2-tp3752179p3752419.html

Eduardo Macarron

unread,
Feb 17, 2012, 5:39:59 AM2/17/12
to mybati...@googlegroups.com

Hi, could you please post the full stacktrace??

byteworks

unread,
Feb 17, 2012, 7:33:45 AM2/17/12
to mybati...@googlegroups.com
Thanks for looking at this Elduardo. I just doesn't like my configuration as
far as parameters are concerned.

<bean id="wordAbbreviationDao"
class="com.watchguard.core.dao.impl.WordAbbreviationDaoImpl"
p:sqlSession-ref="sqlSession" />

Here is the WordAbbreviationDao interface:

WordAbbreviation findByWord(final String word);

Here is the WordAbbreviationDaoImpl:

public WordAbbreviation findByWord(final String word) {
return object(NAME_SPACE + ".findByWord", word);
}

Here is IbatisAbstractDao<T extends Identifiable, ID>

protected T object(String queryName, Object param) {
return (T)getSqlSession().selectOne(queryName, param);
}


I've tried this with and without the parameterType:

<select id="findByWord" parameterType="java.lang.String"
resultMap="get-Result">
SELECT
WORD_ABBREVIATION_ID,
WORD,
ABBREVIATION
FROM
WORD_ABBREVIATION
WHERE
(UPPER(WORD) = UPPER(#{value}))
</select>

[2012-02-16 18:45:33,472] DEBUG org.mybatis.spring.SqlSessionUtils
Registering transaction synchronization for SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@f5d8d75]
[2012-02-16 18:45:33,559] DEBUG java.sql.PreparedStatement ==> Executing:
SELECT WORD_ABBREVIATION_ID, WORD, ABBREVIATION FROM WORD_ABBREVIATION WHERE
(UPPER(WORD) = UPPER(?))
[2012-02-16 18:45:33,559] DEBUG java.sql.PreparedStatement ==> Parameters:
TEST_WORD(String)
[2012-02-16 18:45:33,580] DEBUG org.mybatis.spring.SqlSessionUtils Releasing
transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@f5d8d75]
[2012-02-16 18:45:33,581] DEBUG org.mybatis.spring.SqlSessionUtils Fetched
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@f5d8d75]
from current transaction
[2012-02-16 18:45:33,581] DEBUG java.sql.PreparedStatement ==> Executing:
SELECT WORD_ABBREVIATION_ID, WORD, ABBREVIATION FROM WORD_ABBREVIATION WHERE
(UPPER(WORD) = UPPER(?))
[2012-02-16 18:45:33,582] DEBUG java.sql.PreparedStatement ==> Parameters:
TEST_WORD(String)
[2012-02-16 18:45:33,582] DEBUG org.mybatis.spring.SqlSessionUtils Releasing
transactional SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@f5d8d75]
[2012-02-16 18:45:33,583] DEBUG
org.springframework.test.context.transaction.TransactionalTestExecutionListener
No method-level @Rollback override: using default rollback [true] for test
context [[TestContext@2ce1899b testClass = WordAbbreviationDaoTest,
locations = array<String>['classpath:application-coreContext.xml'],
testInstance = com.watchguard.core.test.dao.WordAbbreviationDaoTest@f581593,
testMethod = testInsert@WordAbbreviationDaoTest, testException =
org.junit.internal.runners.model.MultipleFailureException]]
[2012-02-16 18:45:33,584] DEBUG
org.springframework.jdbc.datasource.DataSourceTransactionManager Initiating
transaction rollback
[2012-02-16 18:45:33,584] DEBUG
org.springframework.jdbc.datasource.DataSourceTransactionManager Rolling
back JDBC transaction on Connection
[com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@3cdf0256]
[2012-02-16 18:45:33,585] DEBUG org.mybatis.spring.SqlSessionUtils
Transaction synchronization closing SqlSession
[org.apache.ibatis.session.defaults.DefaultSqlSession@f5d8d75]
[2012-02-16 18:45:33,586] DEBUG
org.springframework.jdbc.datasource.DataSourceTransactionManager Releasing
JDBC Connection
[com.mysql.jdbc.jdbc2.optional.JDBC4ConnectionWrapper@3cdf0256] after
transaction
[2012-02-16 18:45:33,586] DEBUG
org.springframework.jdbc.datasource.DataSourceUtils Returning JDBC
Connection to DataSource
[2012-02-16 18:45:33,589] INFO
org.springframework.test.context.transaction.TransactionalTestExecutionListener
Rolled back transaction after test execution for test context
[[TestContext@2ce1899b testClass = WordAbbreviationDaoTest, locations =
array<String>['classpath:application-coreContext.xml'], testInstance =
com.watchguard.core.test.dao.WordAbbreviationDaoTest@f581593, testMethod =
testInsert@WordAbbreviationDaoTest, testException =
org.junit.internal.runners.model.MultipleFailureException]]
[2012-02-16 18:45:33,591] DEBUG
org.springframework.test.context.support.DirtiesContextTestExecutionListener
After test method: context [[TestContext@2ce1899b testClass =
WordAbbreviationDaoTest, locations =
array<String>['classpath:application-coreContext.xml'], testInstance =
com.watchguard.core.test.dao.WordAbbreviationDaoTest@f581593, testMethod =
testInsert@WordAbbreviationDaoTest, testException =
org.junit.internal.runners.model.MultipleFailureException]], class dirties
context [false], class mode [null], method dirties context [false].

org.mybatis.spring.MyBatisSystemException: nested exception is
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IllegalArgumentException:
null source
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: java.lang.IllegalArgumentException: null source

at
org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
at $Proxy12.selectOne(Unknown Source)
at
org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:155)
at
com.watchguard.core.dao.IbatisAbstractDao.object(IbatisAbstractDao.java:33)
at
com.watchguard.core.dao.impl.WordAbbreviationDaoImpl.findByWord(WordAbbreviationDaoImpl.java:35)
at
com.watchguard.core.test.dao.WordAbbreviationDaoTest.cleanup(WordAbbreviationDaoTest.java:53)
at
com.watchguard.core.test.dao.WordAbbreviationDaoTest.runBefore(WordAbbreviationDaoTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
at
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.ibatis.exceptions.PersistenceException:

### Error querying database. Cause: java.lang.IllegalArgumentException:
null source
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### Cause: java.lang.IllegalArgumentException: null source

at
org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
at
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:81)
at
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:73)
at
org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:350)
... 38 more
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:38)
at javax.sql.StatementEvent.<init>(StatementEvent.java:39)
at
com.mysql.jdbc.jdbc2.optional.JDBC4PreparedStatementWrapper.close(JDBC4PreparedStatementWrapper.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at
org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:67)
at $Proxy22.close(Unknown Source)
at
org.apache.ibatis.executor.BaseExecutor.closeStatement(BaseExecutor.java:215)
at
org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:43)
at
org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:243)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:117)
at
org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:72)
at
org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:79)
... 45 more

--
View this message in context: http://mybatis-user.963551.n3.nabble.com/SqlMapDaoTemplate-migration-from-iBatis-2-tp3752179p3753522.html

byteworks

unread,
Feb 17, 2012, 8:40:33 AM2/17/12
to mybati...@googlegroups.com
Eduardo,

I downloaded the source, and did some debugging. I'll do more tonight. One
thing I saw in the SimpleExecutor is that when it calls the MySQL driver the
ResultsHandler is null. I don't know if that is normal for no results, or
whether I have a datasource problem. That was a working datasource in
ibatis, so the maybe my mybatis configuration is just set-up wrong.

Here is that part of my configuration:

<bean id="mysqlDataSource"
class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"
p:url = "${connection.url}"
p:user = "${connection.user}"
p:password = "${connection.password}"
/>


<bean id="dataSource"
class="org.apache.commons.dbcp.datasources.SharedPoolDataSource"
lazy-init="false" destroy-method="close"
p:connectionPoolDataSource-ref = "mysqlDataSource"
p:loginTimeout = "${pool.login.timeout}"
p:minEvictableIdleTimeMillis = "${pool.min.evictable.idle}"
p:maxActive = "${pool.max.active}"
p:maxIdle = "${pool.max.idle}"
p:maxWait ="${pool.max.wait}"
p:validationQuery = "${pool.validation.query}"
p:testOnReturn = "${pool.test.on.return}"
p:testWhileIdle = "${pool.test.while.idle}"
p:timeBetweenEvictionRunsMillis =
"${pool.time.between.eviction.runs}"
/>

<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">


<property name="dataSource" ref="dataSource" />

</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"

value="classpath:com/watchguard/core/dao/sqlMapConfig.xml"/>
</bean>

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

<bean id="wordAbbreviationDao"
class="com.watchguard.core.dao.impl.WordAbbreviationDaoImpl"
p:sqlSession-ref="sqlSession" />


How does SqlSessionFactoryBean know about the transactionManager? Am I
wrong to be passing in sqlSession into my DaoImpl? Should that be a factory?


--
View this message in context: http://mybatis-user.963551.n3.nabble.com/SqlMapDaoTemplate-migration-from-iBatis-2-tp3752179p3753684.html

Eduardo

unread,
Feb 18, 2012, 12:44:45 PM2/18/12
to mybatis-user

byteworks

unread,
Feb 18, 2012, 1:54:25 PM2/18/12
to mybati...@googlegroups.com
Nice catch, Eduardo. I just needed to update my dependencies:

mysql-connector-java: 5.1.6 --> 5.1.18
commons-dbcp: 1.2.2 --> 1.4

That fixed it.

--
View this message in context: http://mybatis-user.963551.n3.nabble.com/SqlMapDaoTemplate-migration-from-iBatis-2-tp3752179p3756836.html

Reply all
Reply to author
Forward
0 new messages