0

I am using Hibernate over DB2. When I create a NameQuery with the parameter being a List of enum values, getResultList() throws Illegal converation exception.

@NamedQuery(
        name="Deliverable.deliverableFiles",
        query="Select distinct f " +
                "from Deliverable d JOIN d.deliverableFiles f JOIN f.architectures a " +
                "where d.visibility in (:visibilities) and a.architecture in (:architectures) " +
                "and d.hidden = false and releaseType in (:releaseTypes) "
)

Java method:

public static List<DeliverableFile> getDeliverableFiles(EntityManager em, ArrayList<DeliverableVisibility> visibilities,
                                                 ArrayList<DeliverableArchitectureType> architectures,
                                                 ArrayList<DeliverableReleaseType> releaseTypes, int limit) {
    Query deliverableFiles = em.createNamedQuery("Deliverable.deliverableFiles");
    deliverableFiles.setFlushMode(FlushModeType.COMMIT);
    deliverableFiles.setParameter("visibilities", visibilities);
    deliverableFiles.setParameter("architectures", architectures);
    deliverableFiles.setParameter("releaseTypes", releaseTypes);

    List<DeliverableFile> files;

    try {
        files = deliverableFiles.getResultList();   // exceptions is thrown here
    } // end try
    catch (NoResultException nre) {
        files = null;
    } // end catch

    return files;
} // end getDeliveries()

Exception when method gets called:

    ERROR: [jcc][1083][10406][4.2.73] Illegal conversion: can not convert from "byte[]" to "java.lang.String" ERRORCODE=-4474, SQLSTATE=null
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: [jcc][1083][10406][4.2.73] Illegal conversion: can not convert from "byte[]" to "java.lang.String" ERRORCODE=-4474, SQLSTATE=null
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:266)
    at **hidden**.jpa.main.Deliverable.getDeliverableFiles(Deliverable.java:68)
    at **hidden**.dbtestbed.DBTestbed.main(DBTestbed.java:165)
Caused by: org.hibernate.exception.GenericJDBCException: [jcc][1083][10406][4.2.73] Illegal conversion: can not convert from "byte[]" to "java.lang.String" ERRORCODE=-4474, SQLSTATE=null
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at $Proxy40.setBytes(Unknown Source)
    at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$1.doBind(VarbinaryTypeDescriptor.java:57)
    at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
    at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:66)
    at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:588)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1736)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1697)
    at org.hibernate.loader.Loader.doQuery(Loader.java:832)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:293)
    at org.hibernate.loader.Loader.doList(Loader.java:2382)
    at org.hibernate.loader.Loader.doList(Loader.java:2368)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2198)
    at org.hibernate.loader.Loader.list(Loader.java:2193)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1244)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:257)
    ... 2 more
Caused by: com.ibm.db2.jcc.a.SqlException: [jcc][1083][10406][4.2.73] Illegal conversion: can not convert from "byte[]" to "java.lang.String" ERRORCODE=-4474, SQLSTATE=null
    at com.ibm.db2.jcc.a.cd.a(cd.java:650)
    at com.ibm.db2.jcc.a.cd.a(cd.java:60)
    at com.ibm.db2.jcc.a.cd.a(cd.java:94)
    at com.ibm.db2.jcc.a.gc.a(gc.java:677)
    at com.ibm.db2.jcc.a.vl.a(vl.java:1207)
    at com.ibm.db2.jcc.a.vl.setBytes(vl.java:1174)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setBytes(NewProxyPreparedStatement.java:235)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    ... 24 more

Any hints or clues or thoughts are greatly appreciated.

Hank
  • 121
  • 1
  • 8

2 Answers2

0

parameters visibilities, architectures and releaseTypes are of ArrayList. This is not supported by db2. They have to converted to the correct column format.

String whereCondition1 = "'";
for(string tmp : visibilities){
    whereCondition1 = whereCondition1 + tmp + "','";
}
whereCondition1.subString(0,whereCondition1.length() -1);

You should set make the arraylist into this format

deliverableFiles.setParameter("visibilities", whereCondition1);
Shamis Shukoor
  • 2,515
  • 5
  • 29
  • 33
  • Thank you for the quick response. I am not sure I understand what you mean by converting to the correct column format. In db2, these columns are varchar. JPQL sees them as the corresponding Enums so I can't pass ArrayList. So, how would I pass the enum values as a collection to the named query parameter? Thanks. – Hank Dec 04 '12 at 06:26
  • so the condition has to be iin where in, so the ArrayLists has to be converted to 'String1','String2','String3'... – Shamis Shukoor Dec 04 '12 at 06:31
  • I hardocded: deliverableFiles.setParameter("visibilities", "'INTERNAL'"); JPQL doesn't like that. It wants the enum to be passed to setParameter. I get this: java.lang.IllegalArgumentException: Parameter value ['INTERNAL'] did not match expected type [**hidden**.jpa.enums.DeliverableVisibility] – Hank Dec 04 '12 at 06:51
  • That is essentially the same thing as what when I hardcoded 'INTERNAL' into the setParamter() call but I tried your example too. Unfortunately it results in the java.lang.IllegalArgumentException: Parameter value ['INTERNAL','CUSTOMER','CUSTOMERDEVELOPER'] did not match expected type [/hidden/.jpa.enums.DeliverableVisibility] – Hank Dec 04 '12 at 07:14
  • These attributes are annotated to expect the Enums so I can't pass Strings to them. My next choice would be to use QueryBuilder but I'd like to avoid it. – Hank Dec 04 '12 at 07:19
0

Found the problem - it was a simple typo in the NamedQuery. releaseType attribute wasn't qualified by an alias d. It was supposed to be: d.releaseType in (:releaseTypes). Everything else was correct as far as passing in Enum objects as ArrayList to setParameter().

Hank
  • 121
  • 1
  • 8