org.hibernate.ejb.AbstractQueryImpl#registerParameterBinding throws ClassCastException if
the parameter value is a primitive type array.
----------------------------------------------------------------------------------------------------------------------------------------
Key: HHH-5292
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5292
Project: Hibernate Core
Issue Type: Bug
Components: entity-manager
Affects Versions: 3.5.1
Environment: Hibernate 3.5.1, HSQL 1.8
Reporter: Jürgen Kellerer
When I set a query paramter on a TypedQuery that is a primitive array (in my case byte[])
there will be a ClassCastException inside the method
org.hibernate.ejb.AbstractQueryImpl#registerParameterBinding because the method tries to
cast byte[] to Object[]:
{noformat}
... else if (value.getClass().isArray()) {
final Object[] array = (Object[]) value;
...
{noformat}
*Produces:*
{noformat}
java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object;
at
org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:348)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:359)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at
org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:310)
{noformat}
*Reproduction is easy:*
{noformat}
em.createQuery("SELECT e.stringValue FROM entity e WHERE e.guid = :guid",
String.class).setParameter("guid", new byte[16]);
{noformat}
having entity defined as:
{noformat}
@Entity(name = "entity")
public class Entity {
@Column(length=16)
byte[] guid;
@Column
String stringValue;
}
{noformat}
*Solution:*
The solution to the problem is quite simple. By checking list types only if the direct
type match doesn't return true, the system doesn't have such an issue. The
following patch fixes the bug:
Patch for the method inside org.hibernate.ejb.AbstractQueryImpl.java[274]:
{noformat}
protected void registerParameterBinding(Parameter parameter, Object value) {
final Class<?> targetType = parameter.getParameterType();
if ( value != null && targetType != null ) {
if (!targetType.isInstance(value)) {
if ( Collection.class.isInstance( value ) ) {
final Collection collection = (Collection) value;
// validate the elements...
for ( Object element : collection ) {
if ( ! targetType.isInstance( element ) ) {
throw new IllegalArgumentException(
"Parameter value [" + element + "] was not matching type [" +
targetType.getName() + "]"
);
}
}
} else if ( value.getClass().isArray() ) {
final Object[] array = (Object[]) value;
for ( Object element : array ) {
if ( ! targetType.isInstance( element ) ) {
throw new IllegalArgumentException(
"Parameter value [" + element + "] was not matching type [" +
targetType.getName() + "]"
);
}
}
} else {
throw new IllegalArgumentException(
"Parameter value [" + value + "] was not matching type [" +
targetType.getName() + "]"
);
}
}
}
if ( parameterBindings == null ) {
parameterBindings = new HashMap();
}
parameterBindings.put( parameter, value );
}
{noformat}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira