Steve,
iBatis allows using users' own sql queries. You can absolutely reproduce this exact optimistic locking strategy:
Code:
<result-map name="result" class="com.compagny.Product">
<property name="id" column="ID" columnIndex="1"/>
<property name="updateId" column="UPDATE_ID" columnIndex="2"/>
...
</result>
<mapped-statement name="getProduct" result-map="result">
select id, update_id, product_name, price
from product
where id = #value#
</mapped-statement>
<mapped-statement name="updateProduct">
update product
set update_id = update_id + 1,
product_name = #productName#
price = #price#
where id = #id#
and update_id = #updateId#
</mapped-statement>
<mapped-statement name="insertProduct">
insert int product (id, update_id, product_name, price)
values (#id#, 1, #productName#, #price#)
</mapped-statement>
jpetstore (a sample that comes with Spring distribution) shows how you can use Spring/iBatis to build data driven web applications.