and couldn't find it anywhere in a Ctrl+C / Ctrl+V form.
How to implement optimistic locking under iBatis when there is no standard support for it.
It's quite simple. Implement it by your self.
- implement custom OptimisticLockException or reuse the one from JPA package: javax.persistence
- add new db field named 'version' into entity's table. it should be numerical non-null field with default value defined as 1
- add new field into Entity's class: int version
- Update DAO interface to throw OptimisticLockException (so anybody using this DAO can change his code accordingly)
public interface EntityDao {
void createEntity(Entity entity);
Entity selectEntryById(Long id);
void updateEntity(Entity entity) throws OptimisticLockException;
void deleteEntity(Entity entity);
}
- Update DAO class to process version fields
public class EntityDaoImpl extends SqlMapClientDaoSupport implements EntityDao {
@Override
public void createEntity(final Entity entity) {
getSqlMapClientTemplate().insert("insertEntity", entity);
entity.setVersion(1);
}
@Override
public Entity selectEntryById(final Long id) {
return (Entity) getSqlMapClientTemplate().queryForObject("findEntityById", id);
}
@Override
public void updateEntity(final Entity entity) throws OptimisticLockException {
final int oldVersion = entity.getVersion();
final int newVersion = oldVersion + 1;
final Map<String, Object> params = new HashMap<String, Object>();
params.put("entity", entity);
params.put("oldVersion", oldVersion);
params.put("newVersion", newVersion);
int updateCount = getSqlMapClientTemplate().update("updateEntity", params);
if (updateCount == 0) {
throw new OptimisticLockException("trying to update database with obsolete Entity");
}
entity.setVersion(newVersion);
}
@Override
public void deleteEntity(Entity entity) {
getSqlMapClientTemplate().delete("deleteEntity", entity);
}
}
- Update statements file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap>
<typeAlias alias="Entity" type="yourPackage.domain.Entity"/>
<resultMap id="EntityMap" class="Entity">
<result column="id" property="id"/>
<result column="value" property="value"/>
<result column="version" property="version"/>
</resultMap>
<insert id="insertEntity" parameterClass="Entity">
INSERT INTO entity (id, value, version) VALUES (#id#, #value#, 1)
</insert>
<select id="findEntityById" parameterClass="java.lang.Long" resultClass="Entity" resultMap="EntityMap">
SELECT id, value, version FROM entity WHERE id=#value#
</select>
<update id="updateEntity" parameterClass="java.util.Map">
UPDATE entity
SET
value=#entity.value#
version=#newVersion#
WHERE
id=#entity.id#
AND version=#oldVersion#
</update>
<delete id="deleteEntity" parameterClass="Entity">
DELETE FROM entity WHERE id=#id#
</delete>
</sqlMap>
This comment has been removed by a blog administrator.
ReplyDeletevery thanks
ReplyDelete