私が作業しているレガシーコードでは、UserType属性を含むHibernateモデルがあります。さらに、Oracle最適化では「false」がnullとして格納されます。UserTypeカラムを使用しているHibernateのクエリは、nullSafeSetを使用して変換を行いません。
/**
* Data type for a boolean value stored in a NUMBER oracle column. 1 evaluates
* to true, null evaluates to false.
*
* This is designed for oracle indexing, since null values are not indexed.
*
*
*/
public class BooleanUserType implements UserType {
private static final int[] SQL_TYPES = { Types.INTEGER };
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class<?> returnedClass() {
return Boolean.class;
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
Boolean result = false;
resultSet.getInt(names[0]);
if (!resultSet.wasNull()) {
result = true;
}
return result;
}
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
Boolean input = (Boolean) value;
if (input == null || input == false) {
preparedStatement.setNull(index, Types.INTEGER);
} else {
preparedStatement.setInt(index, 1);
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y)
return true;
if (null == x || null == y)
return false;
return x.equals(y);
}
このBooleanUserTypeは、このためのカラム(編集)モデルとして使用される:エンティティが を更新/保存されているときnullSafeSetの両方呼び出されthis StackOverflow reply
によれば
public class CustomString implements Serializable{ private static final long serialVersionUID = -5311205585865001342L; @Id @Column(name="custom_string_id") private Long id; @Column(name="text") private String text; @Column(name="active") @Type(type="my.org.BooleanUserType") // store false as 'null' -- an Oracle optimization private Boolean active; (...)
クエリパラメータを設定する必要がある場合
ただし、これは私がこのモデルのためにブール値active
の列を使用してクエリを実行すると変換が行われず、予期した結果が得られないため、私が観察している動作ではありません。
私はDBに保存されてCustomStringオブジェクトを持っている:
new CustomString(1, "text", Boolean.FALSE);
私は私が期待するように動作していないクエリを作る:私が代わりにこれを行う
Criteria c = session.createCriteria(CustomString.class);
c.add(Restrictions.eq("active", Boolean.FALSE));
c.list() // No results!
場合、それは動作します:
Criteria c = session.createCriteria(CustomString.class);
c.add(Restrictions.isNull("active"));
c.list() // Expected result!
またの代わりにBoolean.TRUE
でオブジェクトを保存3210を入力し、TRUE
を照会すると正常に動作します。
nullSafeSet
メソッドにデバッグログの行がいくつか追加されていて、クエリの作成時に呼び出されないことを確認できます。
nullSafeSet
実際にHibernateによって呼び出され、何らかの形で期待通りに動作しない場合、または私には何かがありません。別の方法でこれにアプローチする必要がありますか?
代わりにカスタムタイプを使用するのはどうですか? http://learningviacode.blogspot.ie/2011/09/creating-hibernate-custom-type-2.html – mendez8
私はそれについて大きな期待はしていませんが、これをチェックしてみてください。http:// stackoverflow .com/questions/29145693/custom-like-predicate-to-handle-custom-user-defined-types-hibernate-usertype –