自分ではカラムの型に固定長文字列を使った事がなかったので、このような問題に遭遇したことがありませんでした。解決方法の例としては、アプリケーションのコードで毎回やる方法もありますが、ユーザー型(UserType)を使う方法とかもあります。ユーザー型の場合は、以下のような感じのクラスを作ります。
package example.usertype;
public class RightPadUserType implements UserType, ParameterizedType {
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
public Class returnedClass() {
return String.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
return EqualsHelper.equals(x, y);
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
・・・(省略)
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
String value = rs.getString(names[0]);
if(value==null)
return "";
return value;
}
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.NULL);
} else {
st.setString(index, StringUtils.rightPad((String)value, length));
}
}
// カラム長
private int length = 0;
public void setParameterValues(Properties properties) {
if(properties.get("length") != null)
length = Integer.parseInt((String)properties.get("length"));
}
}
trimしてもいいのですが、trimだと検索時にindexが効かず遅くなりそうなので、padする方がよいような気がします。ただ、そうすると、カラム長を教えてあげる必要があります(※1)。以下はhbmで書いた場合の例です。
<hibernate-mapping>
<class name="example.Job" table="Jobs">
・・・
<property name="name">
<type name="example.usertype.RightPadUserType">
<param name="length">10</param> ※1
</type>
</property>
・・・
</class>
</hibernate-mapping>
自動生成する方法を作って工夫しないと面倒そうです。あまりいい方法ではないかもしれません。