I have an enum with a list of states (e.g.)
enum State
{
UP,
DOWN,
RETRY
};
The column in my database is of type enum. When I try to execute a Hibernate query by setting the parameter in the query using setParameter("keyword", State.RETRY);, I receive the error of
Parameter value [RETRY] did not match expected type [package.name.State (n/a)]
In my Glassfish 4.1 server.log for my domain. I am using Hibernate 4.3.6.
In looking at the source code for Hibernate, I see the error occurs because of lines 958-960 in org.hibernate.jpa.spi.BaseQueryImpl:
private static boolean isValidBindValue(Class expectedType, Object value, TemporalType temporalType) {
if ( expectedType.isInstance( value ) ) {
return true;
}
...
return false;
}
isValidBindValue returns false and thus I get the message.
It prints out the String equivalent of the enum value because of this line:
String.format("Parameter value [%s] did not match expected type [%s (%s)]",
bind,
parameterType.getName(),
extractName( temporalType )
)
The bind object is implicitly converted to the String value by calling the toString method on the Object which represents the enum State.RETRY.
So how I can I convince Hibernate that State.RETRY is an instance of State?
It looks like Hibernate updated to the JPA 2.1 spec which is more strict in this commit from April 2013:
https://github.com/hibernate/hibernate-orm/commit/84520cd6e36e9207c41528cf9311cae905a86425
The entity is annotated as follows:
@Basic(optional = false)
@Column(name = "state")
@Enumerated(EnumType.String)
private State state;
Edit:
My RetryState enum is loaded by the EarLibClassLoader. Whereas Query is loaded by the URLClassLoader and the EntityManager is loaded by a different class loader.