Is this a safe approach to implement batch updates with spring-mybatis?

861 views
Skip to first unread message

Rick R

unread,
May 11, 2012, 12:25:21 AM5/11/12
to mybati...@googlegroups.com
This seems to be working but want to make sure it's safe (or the wrong approach.)

Relevant portion of spring config:

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

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="oracleDS"/>
<property name="typeAliasesPackage" value="com.ncs.domain"/>
<property name="typeHandlersPackage" value="com.ncs.typehandler"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ncs.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

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

<bean id="batchService" class="com.ncs.service.BatchService">
<property name="sqlSession" ref="batchSqlSession"/>
</bean>

My 'regular' service classes uses the mappers directly  myMapper.whatever.

My batch calls are made in the batchService... which looks like...

private SqlSession sqlSession;

public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}

public void doSomething() { 
    EQMapper eqMapper = sqlSession.getMapper(EQMapper.class);
    eqMapper.doSomething(...)
}

I'm just not sure it's ok to use the same sqlSessionFactory instance for both the standard mappers and then again in the SqlSessionTemplate used by the batchService (with it set to BATCH) ?
Is it better to make a whole new instance of SqlSessionFactory in my config (using the same datasource instance.)

Thanks




Eduardo Macarron

unread,
May 11, 2012, 12:32:56 AM5/11/12
to mybati...@googlegroups.com
Hi Rick. No problem in using the same factory. You are already doing
it in the right way.

2012/5/11 Rick R <ric...@gmail.com>:

Rick R

unread,
May 11, 2012, 1:12:27 AM5/11/12
to mybati...@googlegroups.com
On Fri, May 11, 2012 at 12:32 AM, Eduardo Macarron <eduardo....@gmail.com> wrote:
Hi Rick. No problem in using the same factory. You are already doing
it in the right way.

Thanks. Your work with spring mybatis (and mybatis) doesn't go unappreciated! Great stuff.



--
Rick R

Rick R

unread,
May 12, 2012, 3:35:06 PM5/12/12
to mybati...@googlegroups.com
On Fri, May 11, 2012 at 12:32 AM, Eduardo Macarron <eduardo....@gmail.com> wrote:
Hi Rick. No problem in using the same factory. You are already doing
it in the right way.

Actually, I think there is an issue with what I'm doing. I think it ends up trying to use a batch process all the time. I noticed it just recently when I got a fk constraint violation and I noticed this error  (note how you actually see the method call complete as well - see highlighted complete log statement )


Now notice if I comment out declaring the batch use in my config 


<!--<bean id="batchSqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--<constructor-arg index="0" ref="sqlSessionFactory" />-->
<!--<constructor-arg index="1" value="BATCH" />-->
<!--</bean>-->

<bean id="batchService" class="com.ncs.service.BatchService">
<!--<property name="sqlSession" ref="batchSqlSession"/>-->
</bean>

and then rerun the delete, notice the difference...


What's the best solution to this?  

Maybe I should pull out the batch processes for certain mappers into their own Mappers and maybe define it as a MapperFactoryBean? I'd prefer to be able to use the same mapper in both a batch and regular context if possible (since sometimes some of the inserts/updates are used with a simple executor type.)  



--
Rick R

Eduardo Macarron

unread,
May 12, 2012, 3:56:47 PM5/12/12
to mybati...@googlegroups.com
That should not happen. :(

MapperScannerConfigurer creates MapperFactoryBeans that create
SqlSessionTemplates out of the SqlSessionFactory using the default
executor type.

So creating another SqlSessionTemplate should not alter that behaviour.

I am not sure how can I help with this. Maybe you could debug inside
your beans to get to the SqlSessionTemplate they have a private
attribute executorType that should be BATCH in the template you are
using in the BatchService and SIMPLE for the rest.

Rick R

unread,
May 12, 2012, 4:17:28 PM5/12/12
to mybati...@googlegroups.com
When I get more time, I'll definitely help to debug. If you have an example online that shows a setup where the same mapper is used in both a batch and simple config, that would be a start for me to look at. In the meantime, I only had three batch operations so I pulled them from their mappers and moved them into a "BatchMapper" to isolate things and this Mapper isn't even part of the MapperScannerConfigurer so my config changed to:
 
        <!-- Standard Mappers:  -->

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="oracleDS"/>
<property name="typeAliasesPackage" value="com.ncs.domain"/>
<property name="typeHandlersPackage" value="com.ncs.typehandler"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ncs.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
        
        <!-- *** For Batch:   -->

<bean id="sqlSessionFactoryForBatch" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="oracleDS"/>
<property name="typeAliasesPackage" value="com.ncs.domain"/>
<property name="typeHandlersPackage" value="com.ncs.typehandler"/>
</bean>

<bean id="batchMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.ncs.batchmapper.BatchMapper"/>
<property name="sqlSessionTemplate">
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactoryForBatch"/>
<constructor-arg index="1" value="BATCH"/>
</bean>
</property>
</bean>



--
Rick R
Reply all
Reply to author
Forward
0 new messages