title: mybatis-spring transaction issue
body: <p>I am having issues using CMT Spring transaction with mybatis, I have a class that uses 2 MapperFactoryBean to insert record.</p>
  <blockquote>
  <p>When inserting records getting FOREIGN KEY constraint exception; it seems both are running in different sessions and the second one could not find the newly inserted id.</p>
  <p>When passing null in second record's foreign key; no exception is thrown but also transaction is not committed.</p>
  <p>Rollback is working fine if any exception is thrown.</p>
  </blockquote>
  <p>Here is my configuration</p>
  <pre><code>    &lt;tx:jta-transaction-manager /&gt;
  
      &lt;bean id=&quot;dataSource&quot; class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;&gt;        
      &lt;property name=&quot;url&quot; value=&quot;${database.url}&quot;/&gt;
      &lt;property name=&quot;driverClassName&quot; value=&quot;${database.driverClassName}&quot;/&gt;
      &lt;property name=&quot;username&quot; value=&quot;${database.username}&quot;/&gt;
      &lt;property name=&quot;password&quot; value=&quot;${database.password}&quot;/&gt;   
      &lt;property name=&quot;defaultAutoCommit&quot; value=&quot;false&quot; /&gt;
      &lt;/bean&gt;
  
      &lt;bean id=&quot;transactionManager&quot; class=&quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&quot;&gt;
      &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot;/&gt;
      &lt;property name=&quot;nestedTransactionAllowed&quot; value=&quot;true&quot; /&gt;
      &lt;property name=&quot;validateExistingTransaction&quot; value=&quot;true&quot; /&gt;
      &lt;/bean&gt;
  
      &lt;bean id=&quot;sqlSessionFactory&quot; class=&quot;org.mybatis.spring.SqlSessionFactoryBean&quot;&gt;
      &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;            
      &lt;property name=&quot;configLocation&quot; value=&quot;classpath:dataAccess-config.xml&quot;/&gt;  
      &lt;/bean&gt;
  
      &lt;bean id=&quot;taskRecordMapper&quot; class=&quot;org.mybatis.spring.MapperFactoryBean&quot;&gt;       
      &lt;property name=&quot;sqlSessionFactory&quot; ref=&quot;sqlSessionFactory&quot; /&gt; 
      &lt;property name=&quot;mapperInterface&quot; value=&quot;TaskRecordMapper&quot;/&gt;
      &lt;/bean&gt;
  
      &lt;bean id=&quot;taskTagRecordMapper&quot; class=&quot;org.mybatis.spring.MapperFactoryBean&quot;&gt;       
      &lt;property name=&quot;sqlSessionFactory&quot; ref=&quot;sqlSessionFactory&quot; /&gt;
      &lt;property name=&quot;mapperInterface&quot; value=&quot;TaskTagRecordMapper&quot;/&gt;
      &lt;/bean&gt;
  </code></pre>
  <p>Code snippet</p>
  <pre><code>    @Transactional(propagation= Propagation.REQUIRED)
      public boolean assignTask(Object source, TaskType taskType, String description,
                                  long assignedTo, long createdBy, long escalationId,
                                  boolean isAssignedToGroup, long parentTaskId,
                                  Date deadline, TaskPriority taskPriority) throws Exception
      {
           
      EntityType entityType = TaskUtil.getEntityType(source);
      long entityId = TaskUtil.getIdFromObject(source);
              
      TaskRecord newTask = new TaskRecord();
      
      newTask.setAssignedTo((isAssignedToGroup) ? null : assignedTo);
      newTask.setCategory(entityType.toString());
      newTask.setCreatedBy(createdBy); 
      newTask.setCreatedOn(new Date());
      newTask.setDeadline(deadline);
      newTask.setDescription(description);
      newTask.setEntityId(entityId);
      newTask.setEscalationId(escalationId); 
      newTask.setIsAssignedToGroup(isAssignedToGroup);
      newTask.setIsDeleted(false);
      newTask.setModifiedBy(null);
      newTask.setModifiedOn(null);
      newTask.setOwner(createdBy); 
      newTask.setParentId((parentTaskId == 0) ? null : parentTaskId);
      newTask.setPriority(taskPriority.toString());
      newTask.setReferenceNo(null);
      newTask.setResult(null);
      newTask.setStatus(TaskStatus.InProgress.toString());
      newTask.setType(taskType.toString());
      
      boolean rValue = taskRecordMapper.insert(newTask) &gt; 0;
      
      
      if(rValue &amp;&amp; isAssignedToGroup)
      {   
          TaskTagRecord tag = new TaskTagRecord();
          
          tag.setTaskId(newTask.getId());
          tag.setName(&quot;RoleId&quot;);
          tag.setValue(String.valueOf(assignedTo));
          
          rValue = taskTagRecordMapper.insert(tag) &gt; 0;
      }
          
      
      return rValue;
      }
  </code></pre>
  <p>Thanks in anticipation</p>
  <p>Here is the Stacktrace</p>
  <pre><code>org.springframework.dao.DataIntegrityViolationException: SqlSession operation; SQL []; The INSERT statement conflicted with the FOREIGN KEY constraint &quot;FK_task_tag_task&quot;. The conflict occurred in database &quot;TEMP&quot;, table &quot;dbo.task&quot;, column 'id'.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The INSERT statement conflicted with the FOREIGN KEY constraint &quot;FK_task_tag_task&quot;. The conflict occurred in database &quot;TEMP&quot;, table &quot;dbo.task&quot;, column 'id'.
      at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:101)
      at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
      at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
      at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
      at org.mybatis.spring.SqlSessionTemplate.wrapException(SqlSessionTemplate.java:364)
      at org.mybatis.spring.SqlSessionTemplate$7$1.doInSqlSession(SqlSessionTemplate.java:344)
      at org.mybatis.spring.SqlSessionTemplate.execute(SqlSessionTemplate.java:173)
      at org.mybatis.spring.SqlSessionTemplate.execute(SqlSessionTemplate.java:155)
      at org.mybatis.spring.SqlSessionTemplate$7.invoke(SqlSessionTemplate.java:339)
      at $Proxy18.insert(Unknown Source)
      at com.task.service.TaskService.assignTask(TaskService.java:184)
      at com.task.service.TaskService.assignTask(TaskService.java:137)
      at com.core.mapper.TaskServiceTest.main(TaskServiceTest.java:38)
  Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The INSERT statement conflicted with the FOREIGN KEY constraint &quot;FK_task_tag_task&quot;. The conflict occurred in database &quot;TEMP&quot;, table &quot;dbo._task&quot;, column 'id'.
      at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:196)
      at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1454)
      at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:388)
      at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:338)
      at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026)
      at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)
      at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:185)
      at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:160)
      at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:320)
      at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:45)
      at $Proxy38.execute(Unknown Source)
      at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:22)
      at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:51)
      at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:29)
      at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:75)
      at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:43)
      at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:118)
      at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:107)
      at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:56)
      at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:38)
      at $Proxy18.insert(Unknown Source)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.mybatis.spring.SqlSessionTemplate$7$1.doInSqlSession(SqlSessionTemplate.java:342)
      ... 7 more
  </code></pre>
  <p>Here is the DEBUG log</p>
  <pre><code>02:41:32,465 INFO  main [ClassPathXmlApplicationContext] Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1bc887b: startup date [Thu May 26 02:41:32 GST 2011]; root of context hierarchy
  02:41:32,512 INFO  main [XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [dataAccessApplicationContext.xml]
  02:41:33,034 INFO  main [DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@173b262: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,org.springframework.context.config.internalBeanConfigurerAspect,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.beans.factory.config.PropertyOverrideConfigurer#0,dataSource,transactionManager,sqlSessionFactory,managedTransactionFactory,springApplicationContext]; root of factory hierarchy
  02:41:34,512 DEBUG main [Connection] ooo Connection Opened
  02:41:34,659 DEBUG main [PreparedStatement] ==&gt;  Executing: select id, order_number, com_id, order_date, status, source, created_on, created_by, is_deleted, modified_on, modified_by from order WHERE ( id = ? and is_deleted = ? ) 
  02:41:34,660 DEBUG main [PreparedStatement] ==&gt; Parameters: 264(Long), false(Boolean)
  02:41:34,699 DEBUG main [ResultSet] &lt;==    Columns: id, order_number, com_id, order_date, status, source, created_on, created_by, is_deleted, modified_on, modified_by
  02:41:34,709 DEBUG main [ResultSet] &lt;==        Row: 264, 00277-100410, 1041, 2010-01-01 00:00:00.0, Pending, COMPANY A, 2011-05-24 00:21:00.337, 1, 0, null, null
  02:41:34,723 DEBUG main [Connection] xxx Connection Closed
  02:41:34,742 DEBUG main [Connection] ooo Connection Opened
  02:41:34,747 DEBUG main [PreparedStatement] ==&gt;  Executing: insert into task (type, status, owner, description, context_id, deadline, assigned_to, parent_id, priority, escalation_id, reference_no, result, created_on, created_by, modified_on, modified_by, category, entity_id, is_deleted, is_assigned_to_group) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
  02:41:34,747 DEBUG main [PreparedStatement] ==&gt; Parameters: Investigation(String), InProgress(String), 1(Long), Please investigate this order(String), null, 2011-05-27 02:41:34.736(Timestamp), null, null, Normal(String), 1(Long), null, null, 2011-05-26 02:41:34.737(Timestamp), 1(Long), null, null, Order(String), 264(Long), false(Boolean), true(Boolean)
  02:41:34,757 DEBUG main [PreparedStatement] ==&gt;  Executing: select @@identity 
  02:41:34,757 DEBUG main [PreparedStatement] ==&gt; Parameters: 
  02:41:34,763 DEBUG main [ResultSet] &lt;==    Columns: 
  02:41:34,763 DEBUG main [ResultSet] &lt;==        Row: 94
  02:41:34,782 DEBUG main [Connection] xxx Connection Closed
  02:41:34,800 DEBUG main [Connection] ooo Connection Opened
  02:41:34,803 DEBUG main [PreparedStatement] ==&gt;  Executing: insert into task_tag (name, value, task_id ) values (?, ?, ? ) 
  02:41:34,804 DEBUG main [PreparedStatement] ==&gt; Parameters: RoleId(String), 1(String), 94(Long)
  02:41:34,842 INFO  main [XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
  02:41:34,859 INFO  main [SQLErrorCodesFactory] SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
  02:41:34,944 DEBUG main [Connection] xxx Connection Closed
  </code></pre>