Hibernate version: 3.0.5
I've been playing around with custom parameterized user types a bit. I'm using the EnumUserType code from the website (
http://hibernate.org/272.html). It works well with CRUD cases, but when you start to use these types with HQL, it seems to fall apart a bit.
Say you have an object Glass, which has an enum in it called State. So the mapping file would look like:
Code:
<hibernate-mapping>
<typedef name="state" class="EnumUserType">
<param name="enumClassName">example.State</param>
</typedef>
<class table="Glass" class="example.Glass">
<id name="id" column="Id" type="int">
<generator class="native" />
</id>
<property name="state" column="State" type="state" />
</class>
</hibernate-mapping>
Then the class:
Code:
public class Glass {
private State state;
public State getState() { return state; }
public void setState(State state) { this.state = state; }
}
public enum State {
FULL, HALF_FULL, HALF_EMPTY, EMPTY;
}
}
Saving, updating, deleting all works fine. But if I try to do an HQL query:
Code:
session.createQuery("from Glass glass where glass.state=:state").setParameter("state", State.FULL).list();
That doesn't work. ':state' will be replaced with a serialized version of the enum, because Hibernate doesn't know what type it is (and an enum is Serializable). And you can't do this either:
Code:
session.createQuery("from Glass glass where glass.state=:state").setParameter("state", State.FULL, Hibernate.custom(EnumUserType.class).list();
Hibernate.custom() will create a new instance of EnumUserType which will need the same parameters from the typedef. I guess you could add the parameters in the call to Hibernate.custom, but thats not very satisfying because you'll have places where you are defining the type, the mapping file and the code.
Assuming I'm not missing anything, it seems that the two ways to fix this are:
1) to create Hibernate.custom(String typedefName). That way you can reference that original typedef that you created.
2) A better solution would be to have Hibernate infer what the UserType should be based on the property you're referencing. So in this case, it should know that 'glass.state' is of type 'state', so the value object must be something that can be handled by that UserType class.
Any thoughts?
--Alex