A forum search shows that this has been discussed before, but the relevant posts I found only seemed to mention CompositeUserType, which I don't believe is appropriate in my case. My Hibernate version is 3.0.5. The following below is a simplification of my actual setup, which I have not actually compiled. Apologies if there are syntax errors.
I want to represent an enumeration of possible states which an entity might have, so I define the following class:
Code:
public class State {
public static final STATE_ONE = new State("one");
public static final STATE_TWO = new State("two");
private String code;
private State(String code) {
this.code = code;
}
public String getCode() {
return code;
}
In order to make it possible to map properties of type State to the database, I write an implementation of UserType named StateUserType:
Code:
public class StateUserType implements UserType {
public int[] sqlTypes() { return new int[] {Types.VARCHAR}; }
public Class returnedClass() { return State.class; }
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) {
String code = rs.getString(names[0]);
if (code == null) return null;
else if (code.equals(State.STATE_ONE.getCode())) return STATE_ONE;
else if (code.equals(State.STATE_TWO.getCode())) return STATE_TWO;
else return null;
}
public void nullSafeSet(PreparedSatatement ps, Object value, int index) {
State s = (State)value;
if (s == null) {
ps.setString(index, null);
} else {
ps.setString(index, s.getCode());
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)value;
}
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
}
Here's the problem: when I try to execute the following HQL statement:
Code:
from SomeEntity e where e.state = ?
and I have supplied State.STATE_ONE as the query parameter, Hibernate serializes the entire STATE_ONE instance and sends it down the wire. If I supply State.STATE_ONE.getCode() as the query parameter, things work correctly. This doesn't feel right to me - my query shouldn't need to know that State is saved by dumping the code to a column. So, what did I botch? I had thought maybe changing the implementation of disassemble() might be the answer, but from my debug output it does not appear disassemble() gets called when the query executes.
In case it's important, I am running my HQL queries through a spring HibernateTemplate using find(), rather than directly through the HibernateSession.