Search code examples
jakarta-eejpajava-ee-7

Unexpected token "?" during JPA query?


I'm attempting to query a list of Api keys in my db2 database.

The problem is that the actual query JPA comes up with has an extra comparison field that is causing a syntax error.

The error:

[ERROR   ] CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getApikeys" on bean "BeanId(WebApiConsole#WebApiConsole.war#ConsoleREST, null)". Exception data: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140222-22988a5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.ibm.db2.jcc.am.SqlSyntaxErrorException: An unexpected token "?" was found following "KEYS t1 WHERE ( LIKE".  Expected tokens may include:  "IN".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.16.53
Error Code: -104
Call: SELECT t1.APIKEYID, t1.APIKEY, t1.CREATEDAT, t1.PROJECTID FROM DB2ADMIN.PROJECTS t0, DB2ADMIN.APIKEYS t1 WHERE ( LIKE ? AND (t0.PROJECTID = t1.PROJECTID))
    bind => [1 parameter bound]
Query: ReadAllQuery(name="Apikey.queryAllByProject" referenceClass=Apikey sql="SELECT t1.APIKEYID, t1.APIKEY, t1.CREATEDAT, t1.PROJECTID FROM DB2ADMIN.PROJECTS t0, DB2ADMIN.APIKEYS t1 WHERE ( LIKE ? AND (t0.PROJECTID = t1.PROJECTID))")

Excerpt. I do not know why the question mark appears.

SELECT t1.APIKEYID, t1.APIKEY, t1.CREATEDAT, t1.PROJECTID FROM DB2ADMIN.PROJECTS t0, DB2ADMIN.APIKEYS t1 WHERE ( LIKE ? AND (t0.PROJECTID = t1.PROJECTID))

The named query:

@NamedQuery(name    = "Apikey.queryAllByProject",
            query   = "SELECT k FROM Apikey k WHERE k.project LIKE :project")

Finally, here is the jax-rs application code:

Project p = (Project) em.createNamedQuery("Project.queryProjectById")
        .setParameter("projectid", Integer.parseInt(projectid)).getResultList().get(0);
List<JsonObject> apikeys = em.createNamedQuery("Apikey.queryAllByProject")
                        .setParameter("project", p)
                        .getResultList();

Strangely enough, it all works out if I change it to the following:

@NamedQuery(name    = "Apikey.queryAllByProject",
            query   = "SELECT k FROM Apikey k WHERE k.project.projectid LIKE :projectid")


List<JsonObject> apikeys = em.createNamedQuery("Apikey.queryAllByProject")
                        .setParameter("projectid", 10000)
                        .getResultList();

Solution

  • LIKE operator cannot be use to compare two entities, there is no way how to express this in SQL language. You will need to fetch them according to the matching id or on some other criterion. See also this table which lists JPA operators and their capabilities.