As shown earlier, there are two primary ways of defining a JDOQL query.
In this guide we describe the declarative approach, defining the individual components of the query
via an API. You can also refer to the API javadoc
We firstly need to look at a typical declarative JDOQL Query.
Query query = pm.newQuery(MyClass.class);
query.setFilter("field2 < threshold");
List results = (List)query.execute(my_threshold);
In this Query, we create it to return objects of type
and set the filter to restrict to instances of that type which have the field
less than some threshold value, which we don't know at that point.
We've specified the query like this because we want to pass the threshold value in dynamically.
We then import the type of our
parameter, and the parameter itself, and set the
of the results from the Query to be in ascending order of some field
The Query is then executed, passing in the threshold value. The example is to highlight the typical
methods specified for a Query. Clearly you may only specify the Query line if you wanted something
very simple. The result of the Query is cast to a List since in this case it returns a List of
Set the class of the candidate instances of the query. The class specifies the class of the
candidates of the query. Elements of the candidate collection that are of the specified class
are filtered before being put into the results.
Specify that only the first result of the query should be returned, rather than a collection.
The execute method will return null if the query result size is 0.
Sometimes you know that the query can only every return 0 or 1 objects. In this case you can
simplify your job by adding
In this case the return from the execution of the Query will be a single Object, so you've no
need to use iterators, just cast it to your candidate class type.
Specifies what type of data this query should return. If this is unset or set to null, this
query returns instances of the query's candidate class. If set, this query will return
expressions, including field values (projections) and aggregate function results.
The normal behaviour of JDOQL queries is to return a List of Objects of the type of the candidate
class. Sometimes you want to have the query perform some processing and return things like count(),
min(), max() etc. You specify this with
query.setResult("count(param1), max(param2), param3");
In this case the results will be List<Object> since there are more than 1 column in each
row. If you have only 1 column in the results then the results would be List<Object>.
If you have only aggregates (sum, avg, min, max, count) in the result clause then there will be
only 1 row in the results and so the results will be of the form Object (or Object if only 1
Please refer to JDOQL Result Clauses for more details.
Specify the type of object in which to return each element of the result of invoking execute().
If the result is not set or set to null, the result class defaults to the candidate class of
the query. If the result consists of one expression, the result class defaults to the type of
that expression. If the result consists of more than one expression, the result class defaults
When you perform a query, using JDOQL or SQL the query will, in general, return a List of objects.
These objects are by default of the same type as the candidate class. This is good for the majority
of situations but there are some situations where you would like to control the output object.
This can be achieved by specifying the
has to meet certain requirements. These are
Can be one of Integer, Long, Short, Float, Double, Character, Byte, Boolean, String,
java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.sql.Date, java.sql.Time,
java.sql.Timestamp, or Object
Can be a user defined class, that has either a constructor taking arguments of the same type
as those returned by the query (in the same order), or has a public put(Object, Object) method,
or public setXXX() methods, or public fields.
Where you have a query returning a single field, you could specify the
one of the first group for example. Where your query returns multiple fields then you can set the
to be your own class. So we could have a query like this
Query query = pm.newQuery(pm.getExtent(Payment.class,false));
query.setFilter("amount > 10.0");
List results = (List)query.execute();
and we define our
public class Price
protected double amount = 0.0;
protected String currency = null;
public Price(double amount, String currency)
this.amount = amount;
this.currency = currency;
In this case our query is returning 2 fields (a Double and a String), and these map onto the constructor
arguments, so DataNucleus will create objects of the
class using that constructor. We could
have provided a class with public fields instead, or provided
methods or a
method. They all work in the same way.
Set the range of results to return. The execution of the query is modified to return only a
subset of results. If the filter would normally return 100 instances, and fromIncl is set
to 50, and toExcl is set to 70, then the first 50 results that would have been returned are
skipped, the next 20 results are returned and the remaining 30 results are ignored.
An implementation should execute the query such that the range algorithm is done at the data
Sometimes you have a Query that returns a large number of objects. You may want to just display
a range of these to your user. In this case you can do
This has the effect of only returning items 10 through to 19 (inclusive) of the query's results.
The clear use of this is where you have a web system and you're displaying paginated data, and
so the user hits page down, so you get the next "n" results.
is implemented efficiently for MySQL, Postgresql, HSQL (using the LIMIT SQL
keyword) and Oracle (using the ROWNUM keyword), with the query only finding the objects required
by the user directly in the datastore. For other RDBMS the query will retrieve all objects up
to the "to" record, and will not pass any unnecessary objects that are before the "from" record.
Set the filter for the query. The filter specification is a String containing a Boolean
expression that is to be evaluated for each of the instances in the candidate collection.
If the filter is not specified, then it defaults to "true", which has the effect of filtering
only for class type.
Set the import statements to be used to identify the fully qualified name of variables or
parameters. Parameters and unbound variables might come from a different class from the
candidate class, and the names need to be declared in an import statement to eliminate
ambiguity. Import statements are specified as a String with semicolon-separated statements.
In JDOQL you can declare parameters and variables. Just like in Java it is often convenient to just
declare a variable as say Date, and then have an import in your Java file importing the
java.util.Date class. The same applies in JDOQL. Where you have defined parameters or variables
in shorthand form, you can specify their imports like this
query.declareImports("import java.util.Locale; import java.util.Date;");
Just like in Java, if you declare your parameters or variables in fully-specified form (for
example "java.util.Date myDate") then you do not need any import.
The JDOQL uses the
declaration to create a
for the query.
During query compilation, the classes used in the query, if not fully qualified, are searched
in this namespace. The type namespace is built with the following:
package of the candidate class
import declarations (if any)
To resolve a class, the JDOQL compiler will use the class fully qualified name to load it, but
if the class is not fully qualified, it will search by prefixing the class name with the
imported package names declared in the type namespace.
All classes loaded by the query must be acessible by either the candidate class classloader,
the PersistenceManager classloader or the current Thread classloader. The search algorithm for
a class in the JDOQL compiler is the following:
if the class is fully qualified, load the class.
if the class is not fully qualified, iterate each package in the type namespace and try to
load the class from that package. This is done until the class is loaded, or the type
namespace package names are exausted. If the class cannot be loaded an exception is thrown.
Note that the search algorithm can be problematic in performance terms if the class is not
fully qualified or declared in imports using package notation. To avoid such problems, either
use fully qualified class names or import the class in the imports declaration. The 2 queries
below are examples of good usage:
However, the below example will suffer in performance, due to the search algorithm.
query.declareImports("import java.math.*; import java.util.*;");
Declare the list of parameters query execution. The parameter declaration is a String containing
one or more query parameter declarations separated with commas. Each parameter named in the
parameter declaration must be bound to a value when the query is executed.
When using explicit parameters you need to declare them and their types. With the declarative API
you do it like this
query.declareParameters("String myparam1, Date myparam2");
So we make use of
to define some package names (just like in Java). You can use
* notation too. Note that
is not needed to be imported.
Alternatively you could have just done
query.declareParameters("java.lang.String myparam1, java.util.Date myparam2");
Declare the unbound variables to be used in the query. Variables might be used in the filter,
and these variables must be declared with their type. The unbound variable declaration is a
String containing one or more unbound variable declarations separated with semicolons.
With explicit variables, you declare your variables and their types. In declarative JDOQL it
is like this
Multiple variables can be declared using semi-colon (
) to separate variable declarations.
query.declareVariables("String var1; String var2");
Set the candidate Collection to query.
Used where you have some instances and want to know which pass a specified filter.
This will result in the query being performed in-memory rather than in the datastore.
If you don't want to query instances in the datastore but instead query a collection of
candidate instances, you can do this by setting the candidates, like this
Query query = pm.newQuery(Product.class);
query.setFilter("value < 50");
List<Product> results = (List<Product>)query.execute();
This will process the query in-memory.
Set the ordering specification for the result Collection. The ordering specification is a
String containing one or more ordering declarations separated by commas. Each ordering
declaration is the name of the field on which to order the results followed by one of the
following words: "ascending" or "descending". The field must be declared in the candidate
class or must be a navigation expression starting with a field in the candidate class.
With JDOQL you can specify the ordering using the normal JDOQL syntax for a parameter, and then
(UPPER or lower case are both valid) are to give the
direction. In addition the abbreviated forms of
(again, UPPER and
lower case forms are accepted) to save typing. For example, you may set the ordering as follows
Set the grouping expressions, optionally including a "having" clause. When grouping is
specified, each result expression must either be an expression contained in the grouping,
or an aggregate evaluated once per group.