Author: lmeadors
Date: Mon Sep 3 14:41:03 2007
New Revision: 572429
URL: http://svn.apache.org/viewvc?rev=572429&view=rev
Log:
Rolling back generated keys when an insert fails.
Modified:
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/SelectKeyStatement.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/StatementTest.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/maps/LineItem.xml
Modified:
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java?rev=572429&r1=572428&r2=572429&view=diff
==============================================================================
---
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
(original)
+++
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/impl/SqlMapExecutorDelegate.java
Mon Sep 3 14:41:03 2007
@@ -358,13 +358,27 @@
selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement();
}
+ // Here we get the old value for the key property. We'll want it later
if for some reason the
+ // insert fails.
+ Object oldKeyValue = null;
+ String keyProperty = null;
+ boolean resetKeyValueOnFailure = false;
if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) {
+ keyProperty = selectKeyStatement.getKeyProperty();
+ oldKeyValue = PROBE.getObject(param, keyProperty);
generatedKey = executeSelectKey(sessionScope, trans, ms, param);
+ resetKeyValueOnFailure = true;
}
StatementScope statementScope = beginStatementScope(sessionScope, ms);
try {
ms.executeUpdate(statementScope, trans, param);
+ }catch (SQLException e){
+ // uh-oh, the insert failed, so if we set the reset flag earlier,
we'll put the old value
+ // back...
+ if(resetKeyValueOnFailure) PROBE.setObject(param, keyProperty,
oldKeyValue);
+ // ...and still throw the exception.
+ throw e;
} finally {
endStatementScope(statementScope);
}
Modified:
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/SelectKeyStatement.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/SelectKeyStatement.java?rev=572429&r1=572428&r2=572429&view=diff
==============================================================================
---
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/SelectKeyStatement.java
(original)
+++
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapping/statement/SelectKeyStatement.java
Mon Sep 3 14:41:03 2007
@@ -45,7 +45,7 @@
public List executeQueryForList(StatementScope statementScope, Transaction
trans, Object parameterObject, int skipResults, int maxResults)
throws SQLException {
- throw new SQLException("Select statements cannot be executed for a list.");
+ throw new SQLException("Select Key statements cannot be executed for a
list.");
}
public void executeQueryWithRowHandler(StatementScope statementScope,
Transaction trans, Object parameterObject, RowHandler rowHandler)
Modified:
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/StatementTest.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/StatementTest.java?rev=572429&r1=572428&r2=572429&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/StatementTest.java
(original)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/StatementTest.java
Mon Sep 3 14:41:03 2007
@@ -685,6 +685,28 @@
assertEquals(10, testItem.getId());
}
+ public void testInsertGeneratedKeyFailure() throws SQLException {
+ LineItem item = new LineItem();
+
+ item.setId(0);
+ item.setItemCode("blah");
+ item.setOrderId(333);
+ item.setPrice(new BigDecimal("44.00"));
+ item.setQuantity(1);
+
+ Object key = new Integer(-1);
+
+ try{
+ key = sqlMap.insert("insertLineItemOrDie", item);
+ }catch(SQLException e){
+ // this is expected
+ }
+
+ assertEquals(key, new Integer(-1)); // this should not be changed from
above
+ assertEquals(0, item.getId()); // this should not be changed from above
+
+ }
+
public void testInsertPreKey() throws SQLException {
LineItem item = new LineItem();
Modified:
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/maps/LineItem.xml
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/maps/LineItem.xml?rev=572429&r1=572428&r2=572429&view=diff
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/maps/LineItem.xml
(original)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/maps/LineItem.xml
Mon Sep 3 14:41:03 2007
@@ -58,6 +58,16 @@
(#id#, #orderId#, #itemCode#, #quantity#, #price#)
</insert>
+ <insert id="insertLineItemOrDie" parameterClass="testdomain.LineItem">
+ <selectKey resultClass="int" keyProperty="id" type="post">
+ select 99 from LINE_ITEM where LIN_ID = 1 and LIN_ORD_ID=1
+ </selectKey>
+ insert into LINE_ITEM_LOL
+ (LIN_ID, LIN_ORD_ID, LIN_ITM_CODE, LIN_QUANTITY, LIN_PRICE)
+ values
+ (#id#, #orderId#, #itemCode#, #quantity#, #price#)
+ </insert>
+
<insert id="insertLineItemPreKey" parameterClass="testdomain.LineItem">
<selectKey resultClass="int" keyProperty="id">
select 99 from LINE_ITEM where LIN_ID = 1 and LIN_ORD_ID=1