Search code examples
javaspringtransactionsibatis

MyIbatis-Spring Transaction closeSession


When I use MyIbatis with spring transaction, using the Annotation driven declarative method, do I have do bother manage the session.

Without the transaction I usually do like this:

public int insertPnt(Movimenti value) {
    try (SqlSession session = sqlSessionFactory.openSession()) {
    for (Movimenti value : values) {
        session.insert(
                    "com.sirio.cisl.dal.MovimentiMapper.insertSelective",
                    value);
        }
    } catch (Exception e) {
        log.error("Error inserting movimenti "+user+" anno "+anno+" "+ e.getMessage());
        throw e;
    }
}

but from MyIbatis-Spring documentation I read

MyBatis SqlSession provides you with specific methods to handle transactions programmatically. ........... . That means that Spring will always handle your transactions. You cannot call SqlSession.commit(), SqlSession.rollback() or SqlSession.close() over a Spring managed SqlSession.

So I wandering if I'm doing correct when I just adding the @Transaction annotation (and the <tx:annotation-driven> config) to the method.

@Transactional(rollbackFor=Exception.class)
public int insertPnt(Movimenti value) {
    try (SqlSession session = sqlSessionFactory.openSession()) {

    ..............

}

Does the transaction manager take care of the session resourse? Or I have to remove the try-catch clause.

Thk


Solution

  • I post the same question to the MyIbatis-user group see. The response was useful:

    To use MyBatis you need either an SqlSesion or a Mapper interface. With "classic" MyBatis you get the sessions out of an SqlSessionFactory but when using Spring this changes.

    So I follow the example of the documentation: I inject the Service class with a sqlSessionTemplate that internally takes care of opening and close the session.

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:myibatis.xml"/>
        <property name="mapperLocations" value="classpath*:mappers/*.xml" />
    </bean>
    
    
    <bean id="asTableService" class="com.sirio.cisl.dal.AsTableService">
        <property name="session" ref="sqlSession" />
    </bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
      <constructor-arg index="0" ref="sqlSessionFactory" />
      <constructor-arg index="1" value="BATCH" />
    </bean>
    

    Then I can use the @Transactional annotation :

    @Transactional(rollbackFor=Exception.class)
    public int insertPnt(Movimenti value) {
          session.create(......)
     }
    

    Davide