Thanks for the reply, David.
I have created OracleStringType which evaluates null and an empty string be equal, so null/empty string difference is considered to be dirty when using select-before-update.
It seems to work fine, but I wonder if hashCode implementation causes any problems somewhere. (null does not have hashCode, but null and an empty string is equivalent, which breaks the contracts of equals and hashCode?)
Code:
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class OracleStringType implements UserType {
public OracleStringType() {
}
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
public Class returnedClass() {
return String.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
if ((x == y) || (x != null && y != null && x.equals(y))) return true;
if (((x == null) || ("".equals(x))) && ((y == null) || ("".equals(y)))) return true; // null and an empty string are the equivalent
return false;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
return rs.getString(names[0]); // empty string is never returned from oracle
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
st.setString(index, (String)value); // empty string is converted to NULL in oracle
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object value) throws HibernateException {
return (value == null) ? null : (Serializable)deepCopy(value);
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return (cached == null) ? null : deepCopy(cached);
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}