S2JDBC をちょっといじってみました。

S2JDBCを調査していていて、以下の1点だけできないことがあったので自分で実装してみました。
「できないこと」とは、テーブルのUpdateTime等のカラムを getdate()関数の値で UpdateやInsertを実行することが SQLの自動生成ではできないことです。多少わがままな願いかもしれませんが、そのためだけに SQLの自動生成を捨てて SQLファイルを作るのが嫌だったので、自動生成のクラスをオーバーライドして、自前実装を作ってみました。
色々と突っ込みどころ満載だと思いますので、どんどん突っ込みよろしくです。

AutoUpdateSetGetdateImpl.java

package org.seasar.extension.jdbc.extend;

import java.util.List;
import java.util.Set;

import org.seasar.extension.jdbc.AutoUpdate;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.manager.JdbcManagerImplementor;
import org.seasar.extension.jdbc.query.AutoUpdateImpl;
import org.seasar.framework.util.tiger.CollectionsUtil;

/**
 * <p>AutoUpdateExtendedImpl</p>
 */
public class AutoUpdateSetGetdateImpl<T> extends AutoUpdateImpl<T> implements AutoUpdate<T> {

	protected final Set<String> getdateColumnSet_ = CollectionsUtil.newHashSet();
	/**
	 * AutoUpdateExtendedImpl
	 * @param jdbcManager
	 * @param entity
	 * @param columns
	 */
	public AutoUpdateSetGetdateImpl(JdbcManagerImplementor jdbcManager, T entity, String... columns) {
		super(jdbcManager, entity);

		for (final String column: columns) {
			getdateColumnSet_.add(column);
		}
	}

	@Override
	protected void prepareSetClause() {
		List<PropertyMeta> removeList = CollectionsUtil.newArrayList();
		for (final PropertyMeta propertyMeta : targetProperties) {
			if (getdateColumnSet_.contains(propertyMeta.getField().getName())) {
				setClause.addSql(propertyMeta.getColumnMeta().getName(), "getdate()");
				removeList.add(propertyMeta);
			} else {
				setClause.addSql(propertyMeta.getColumnMeta().getName());
			}
		}
		if (!includeVersion && entityMeta.hasVersionPropertyMeta()) {
			final PropertyMeta propertyMeta = entityMeta.getVersionPropertyMeta();
			final String columnName = propertyMeta.getColumnMeta().getName();
			setClause.addSql(columnName, columnName + " + 1");
		}

		for (final PropertyMeta propertyMeta : removeList) {
			targetProperties.remove(propertyMeta);
		}
	}
}

AutoInsertSetGetdateImpl.java

package org.seasar.extension.jdbc.extend;

import java.util.List;
import java.util.Set;

import org.seasar.extension.jdbc.AutoInsert;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.manager.JdbcManagerImplementor;
import org.seasar.extension.jdbc.query.AutoInsertImpl;
import org.seasar.framework.util.tiger.CollectionsUtil;

/**
 * <p>AutoInsertSetGetdateImpl</p>
 */
public class AutoInsertSetGetdateImpl<T> extends AutoInsertImpl<T> implements AutoInsert<T> {

	protected final Set<String> getdateColumnSet_ = CollectionsUtil.newHashSet();
	/**
	 * AutoInsertSetGetdateImpl
	 * @param jdbcManager
	 * @param entity
	 * @param columns
	 */
	public AutoInsertSetGetdateImpl(JdbcManagerImplementor jdbcManager, T entity, String... columns) {
		super(jdbcManager, entity);

		for (final String column: columns) {
			getdateColumnSet_.add(column);
		}
	}

	@Override
	protected void prepareValuesClause() {
		List<PropertyMeta> removeList = CollectionsUtil.newArrayList();
		for (final PropertyMeta propertyMeta : targetProperties) {
			if (getdateColumnSet_.contains(propertyMeta.getField().getName())) {
				valuesClause.addSql("getdate()");
				removeList.add(propertyMeta);
			} else {
				valuesClause.addSql();
			}
		}

		for (final PropertyMeta propertyMeta : removeList) {
			targetProperties.remove(propertyMeta);
		}
	}
}

JdbcManagerSetGetdateImpl.java

package org.seasar.extension.jdbc.extend;

import org.seasar.extension.jdbc.AutoInsert;
import org.seasar.extension.jdbc.AutoUpdate;
import org.seasar.extension.jdbc.EntityMeta;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.exception.NoIdPropertyRuntimeException;
import org.seasar.extension.jdbc.manager.JdbcManagerImpl;
import org.seasar.extension.jdbc.manager.JdbcManagerImplementor;

/**
 * <p>JdbcManagerSetGetdateImpl</p>
 */
public class JdbcManagerSetGetdateImpl extends JdbcManagerImpl implements JdbcManager, JdbcManagerImplementor {
	private static final String[] GETDATE_COLUMNS = new String[] {"updateTime", "createTime"};

	/**
	 * JdbcManagerSetGetdateImpl
	 */
	public JdbcManagerSetGetdateImpl() {
	}

	@Override
	public <T> AutoInsert<T> insert(final T entity) {
		return new AutoInsertSetGetdateImpl<T>(this, entity, GETDATE_COLUMNS).queryTimeout(queryTimeout);
	}

	@Override
	public <T> AutoUpdate<T> update(final T entity) {
		final EntityMeta entityMeta = entityMetaFactory.getEntityMeta(entity.getClass());
		if (entityMeta.getIdPropertyMetaList().isEmpty()) {
			throw new NoIdPropertyRuntimeException("ESSR0761", entityMeta.getName());
		}
		return new AutoUpdateSetGetdateImpl<T>(this, entity, GETDATE_COLUMNS).queryTimeout(queryTimeout);
	}
}

以上の3ファイルを作った後に、s2jdbc.dicon をこっちのJDBCManagerを使うように変更します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
	"http://www.seasar.org/dtd/components24.dtd">
<components>
	<include path="jdbc.dicon"/>
	<include path="s2jdbc-internal.dicon"/>
	<component name="jdbcManager" class="org.seasar.extension.jdbc.extend.JdbcManagerSetGetdateImpl">
		<property name="maxRows">0</property>
		<property name="fetchSize">0</property>
		<property name="queryTimeout">0</property>
		<property name="dialect">hsqlDialect</property>
	</component>
</components>

以上で、以下のようなコードを実行すると、Entityの updateTimeと createTimeのフィールドが getdate()で更新されるようになります。

package jp.ifp.xdss.manager.entity;

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Entity {
	@Id
	@GeneratedValue
	public int id;

	public String name;

	public String note;

	public Timestamp updateTime;

	@Column(updatable = false)
	public Timestamp createTime;
}
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.where.SimpleWhere;
import org.seasar.extension.unit.S2TestCase;

public class UpdateEntityTest extends S2TestCase {

	private JdbcManager jdbcManager;

	@Override
	protected void setUp() throws Exception {
		include("app.dicon");
	}


	public void testUpdateTx() throws Exception {
		Entity entity = new Entity();
		entity.name = "Insert";
		jdbcManager.insert(entity).execute();

		entity.name = "Updated";
		jdbcManager.update(entity).execute();
	}
}