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.