views:

40

answers:

2

I'm trying to construct a JDOQL query (using datanucleus) that will search for matches of a parent class based on criteria in an owned one-to-many child class. The query looks like this:

    Query lQ = lPm.newQuery("select from "+Module.class.getName()+
            " where moduleMappings.contains(m)" +
            " && showNameParam.matches(m.criteria.trim())");
    lQ.declareVariables(ModuleMapping.class.getName()+" m");
    lQ.declareParameters("String showNameParam");

lRet = (List<Module>) lQ.execute("StarTrek");

My data set looks something like this:

  • Module[1]
    • ModuleMapping[1]: criteria=".*"
  • Module[2]
    • ModuleMapping[1]: criteria=".*StarTrek.*"
    • ModuleMapping[2]: criteria=".*StarWars.*"

The query never matches on anything! However, if I replace the argument to the matches JDOQL method with a literal:

Query lQ = lPm.newQuery("select from "+Module.class.getName()+
            " where moduleMappings.contains(m)" +
            " && showNameParam.matches('.*StarTrek.*')");

Things will work for that single example, and my query will find Module[2]. What am I missing? Am I not allowed to use the contents of a mapped field as the argument to a JDOQL method? Do I need to escape things in some way?

Dave

+1  A: 

The log would obviously tell you what SQL is being invoked for your query. You could also address why you are mixing API JDOQL and single-string JDOQL ... definition of parameters/variables should be in the single-string if using single-string.

DataNucleus
A: 

So I figured this out, although to me it seems like a bug in either JDOQL or datanucleus. When using a mapped field as the argument to the matches method, the generated SQL does not translate the JDOQL syntax to the syntax of the data store (in my case, SQL). So in my example above, if I change the criteria fields to use SQL wildcard syntax rather than JDOQL syntax things will start to work.

Specifically, if in my example above I use criteria="%StarTrek%" rather than criteria=".*StarTrek.*" the JDOQL queries will start to match.

This doesn't seem right to me as different data stores could use different matching syntax, but this workaround gets me moving again...

If you think something is a bug then you provide a testcase and a statement of what feature of the spec is not correctly implemented (and the JDO TCK does have tests for such things, but maybe yours is some other situation ... we won't know til we see your testcase). Needless to say, looking at the SQL invoked (as I put in the reply) is the only way to debug things, and you present no evidence of this
DataNucleus
Fair enough, I'll look into filing a bug report, although I'm not 100% sure this is a bug. I'm not yet familiar enough with JDOQL spec to be sure.
As you can see from the very end of the SQL above, "WHERE 'Glee' LIKE B0.CRITERIA ESCAPE '\\'", there is no attempt to transform the contents of B0.CRITERIA from JDOQL syntax to native datastore syntax, thus the need to use SQL wildcard syntax in my CRITERIA field rather than JDOQL syntax.
Hence it obeys the JDO spec then. i.e when hardcoding a matches clause into the JDOQL it follows Java regexp syntax. The JDO spec says nothing about what is contained in a field when that field is used in the matches clause
DataNucleus
Can you suggest a portable way to accomplish this then? Is there a way that I could manually escape JDOQL wildcard to datastore and thus keep my implementation portable?