S2JDBCで日時型にJoda-Timeを使用する

例はPostgreSQL(8.0以前)だが、継承するDialectを変えれば他のDBでも同じようにできるはず

```CustomPostgreDialect.java
package sample.dialect;

import javax.persistence.TemporalType;

import org.joda.time.DateTime;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.ValueType;
import org.seasar.extension.jdbc.dialect.PostgreDialect;

import sample.types.DateTimeTimestampType;

public class CustomPostgreDialect extends PostgreDialect {
	private static final ValueType DATETIME_TIMESTAMP = new DateTimeTimestampType();

	@Override
	public ValueType getValueType(PropertyMeta propertyMeta) {
		if (DateTime.class == propertyMeta.getPropertyClass()) {
			return DATETIME_TIMESTAMP;
		}
		return super.getValueType(propertyMeta);
	}

	@Override
	public ValueType getValueType(Class<?> clazz, boolean lob,
			TemporalType temporalType) {
		if (DateTime.class == clazz) {
			return DATETIME_TIMESTAMP;
		}
		return super.getValueType(clazz, lob, temporalType);
	}
}
```

```DateTimeTimestampType.java
package sample.types;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import org.joda.time.DateTime;
import org.seasar.extension.jdbc.types.DateTimestampType;

public class DateTimeTimestampType extends DateTimestampType {
	@Override
	public Object getValue(ResultSet resultSet, int index) throws SQLException {
		return toDateTimeFromDate(resultSet.getTimestamp(index));
	}

	@Override
	public Object getValue(ResultSet resultSet, String columnName)
			throws SQLException {
		return toDateTimeFromDate(resultSet.getTimestamp(columnName));
	}

	@Override
	public Object getValue(CallableStatement cs, int index) throws SQLException {
		return toDateTimeFromDate(cs.getTimestamp(index));
	}

	@Override
	public Object getValue(CallableStatement cs, String parameterName)
			throws SQLException {
		return toDateTimeFromDate(cs.getTimestamp(parameterName));
	}

	@Override
	protected Date toDate(Object value) {
		if (value instanceof DateTime) {
			return toDateFromDateTime((DateTime) value);
		}
		return super.toDate(value);
	}

	/**
	 * {@link Date}から{@link DateTime}に変換する.
	 * 
	 * @param date
	 *            {@link Date}の値
	 * @return {@link DateTime}の値
	 */
	protected DateTime toDateTimeFromDate(Date date) {
		if (date == null) {
			return null;
		}
		return new DateTime(date);
	}

	/**
	 * {@link DateTime}から{@link Date}に変換する.
	 * 
	 * @param dateTime
	 *            {@link DateTime}の値
	 * @return {@link Date}の値
	 */
	protected Date toDateFromDateTime(DateTime dateTime) {
		if (dateTime == null) {
			return null;
		}
		return dateTime.toDate();
	}
}
```

[S2JDBCの拡張方法](http://qiita.com/items/83da36742110b1247b16 "S2JDBCの拡張方法")

```s2jdbc.diconのdialect部
		<property name="dialect">
			<component class="sample.dialect.CustomPostgreDialect" />
		</property>
```

エンティティクラスで使用する場合は下記のようにする

```
    @Column
    public DateTime dateTime;
```

s2jdbc-genとの連携は一切考慮してないので注意
動作確認中なので不具合があったら是非教えて下さい。

- - -

[Seasar2 - S2JDBC - エンティティ#時制定義](http://s2container.seasar.org/2.4/ja/s2jdbc_entity.html#時制定義)
時制定義(上記URL)に対応するため、
DialectのgetValueTypeメソッドでTemporalTypeの値を取得して
ValueTypeを振り分ける処理も入れようと思ったが
java.util.Dateとjava.util.Calendar以外の型だとTemporalTypeが取得できない。
PropertyMetaFactoryを拡張する必要がありそう。
機会があればそちらの拡張も挑戦してみます。