Author: cbegin Date: Thu Oct 8 03:22:29 2009 New Revision: 823010 URL: http://svn.apache.org/viewvc?rev=823010&view=rev Log: IBATIS-656 selectKey order="BEFORE" does not work with dynamic sql IBATIS-647 iBATIS don't cache selects
Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/CachingExecutor.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/ExecutorTestHelper.java Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/CachingExecutor.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/CachingExecutor.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/CachingExecutor.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/CachingExecutor.java Thu Oct 8 03:22:29 2009 @@ -25,6 +25,7 @@ public void close() { delegate.close(); + tcm.commit(); } public boolean isClosed() { Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/BaseStatementHandler.java Thu Oct 8 03:22:29 2009 @@ -1,12 +1,14 @@ package org.apache.ibatis.executor.statement; import org.apache.ibatis.executor.*; +import org.apache.ibatis.executor.keygen.SelectKeyGenerator; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apache.ibatis.executor.result.ResultHandler; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.executor.resultset.RowLimit; import org.apache.ibatis.mapping.*; import org.apache.ibatis.reflection.factory.ObjectFactory; +import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.type.TypeHandlerRegistry; import java.sql.*; @@ -99,4 +101,20 @@ } + protected void rebindGeneratedKey(){ + if (boundSql.getParameterObject() != null) { + String keyStatementName = mappedStatement.getId() + SelectKeyGenerator.SELECT_KEY_SUFFIX; + if(configuration.hasStatement(keyStatementName)) { + MappedStatement keyStatement = configuration.getMappedStatement(keyStatementName); + if (keyStatement != null) { + String keyProperty = keyStatement.getKeyProperty(); + MetaObject metaParam = MetaObject.forObject(boundSql.getParameterObject()); + if (keyProperty != null && metaParam.hasSetter(keyProperty) && metaParam.hasGetter(keyProperty)) { + boundSql.setAdditionalParameter(keyProperty, metaParam.getValue(keyProperty)); + } + } + } + } + } + } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java Thu Oct 8 03:22:29 2009 @@ -54,6 +54,7 @@ public void parameterize(Statement statement) throws SQLException { KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); keyGenerator.processBefore(executor, mappedStatement, statement, boundSql.getParameterObject()); + rebindGeneratedKey(); registerOutputParameters((CallableStatement) statement); parameterHandler.setParameters((CallableStatement) statement); } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java Thu Oct 8 03:22:29 2009 @@ -54,6 +54,7 @@ throws SQLException { KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); keyGenerator.processBefore(executor, mappedStatement, statement, boundSql.getParameterObject()); + rebindGeneratedKey(); parameterHandler.setParameters((PreparedStatement) statement); } Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java Thu Oct 8 03:22:29 2009 @@ -27,6 +27,34 @@ config.setDefaultStatementTimeout(5000); } + @Test + public void shouldInsertNewAuthorWithBeforeAutoKey() throws Exception { + DataSource ds = createBlogDataSource(); + Connection connection = ds.getConnection(); + try { + Executor executor = createExecutor(new JdbcTransaction(connection, false)); + Author author = new Author(-1, "someone", "******", "some...@apache.org", null, Section.NEWS); + MappedStatement insertStatement = ExecutorTestHelper.prepareInsertAuthorMappedStatementWithBeforeAutoKey(config); + MappedStatement selectStatement = ExecutorTestHelper.prepareSelectOneAuthorMappedStatement(config); + int rows = executor.update(insertStatement, author); + assertTrue(rows > 0 || rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE); + if (rows == BatchExecutor.BATCH_UPDATE_RETURN_VALUE) { + executor.flushStatements(); + } + assertEquals(123456, author.getId()); + if (author.getId() != BatchExecutor.BATCH_UPDATE_RETURN_VALUE) { + List<Author> authors = executor.query(selectStatement, author.getId(), RowLimit.DEFAULT, Executor.NO_RESULT_HANDLER); + executor.rollback(true); + assertEquals(1, authors.size()); + assertEquals(author.toString(), authors.get(0).toString()); + assertTrue(author.getId() >= 10000); + } + } finally { + connection.rollback(); + connection.close(); + } + } + @Test public void shouldInsertNewAuthor() throws Exception { DataSource ds = createBlogDataSource(); Modified: ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/ExecutorTestHelper.java URL: http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/ExecutorTestHelper.java?rev=823010&r1=823009&r2=823010&view=diff ============================================================================== --- ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/ExecutorTestHelper.java (original) +++ ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/executor/ExecutorTestHelper.java Thu Oct 8 03:22:29 2009 @@ -2,10 +2,13 @@ import domain.blog.*; import org.apache.ibatis.builder.StaticSqlSource; +import org.apache.ibatis.builder.xml.dynamic.DynamicSqlSource; +import org.apache.ibatis.builder.xml.dynamic.TextSqlNode; import org.apache.ibatis.cache.Cache; import org.apache.ibatis.cache.decorators.*; import org.apache.ibatis.cache.impl.PerpetualCache; import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; +import org.apache.ibatis.executor.keygen.SelectKeyGenerator; import org.apache.ibatis.mapping.*; import org.apache.ibatis.type.*; @@ -595,4 +598,39 @@ }).build(); } + + public static MappedStatement prepareInsertAuthorMappedStatementWithBeforeAutoKey(final Configuration config) { + final TypeHandlerRegistry registry = config.getTypeHandlerRegistry(); + final ResultMap rm = new ResultMap.Builder(config, "keyResultMap", Integer.class, new ArrayList<ResultMapping>()) + .build(); + + MappedStatement kms = new MappedStatement.Builder(config, "insertAuthor!selectKey", new StaticSqlSource("SELECT 123456 as id FROM SYSIBM.SYSDUMMY1"), SqlCommandType.SELECT) + .keyProperty("id") + .resultMaps(new ArrayList<ResultMap>() { + { + add(rm); + } + }) + .build(); + config.addMappedStatement(kms); + MappedStatement ms = new MappedStatement.Builder(config, "insertAuthor", new DynamicSqlSource(config, new TextSqlNode("INSERT INTO author (id,username,password,email,bio,favourite_section) values(#{id},#{username},#{password},#{email},#{bio:VARCHAR},#{favouriteSection})")), SqlCommandType.INSERT) + .parameterMap( + new ParameterMap.Builder(config, "defaultParameterMap", Author.class, new ArrayList<ParameterMapping>() { + { + add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(Integer.class)).build()); + add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).build()); + add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).build()); + add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).build()); + add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).build()); + add(new ParameterMapping.Builder(config, "favouriteSection", registry.getTypeHandler(Section.class)).jdbcType(JdbcType.VARCHAR).build()); + } + }).build()) + .cache(authorCache) + .keyGenerator(new SelectKeyGenerator(kms, true)) + .keyProperty("id") + .build(); + return ms; + } + + }