Using server queries internally
The ome.services.queries package is intended to allow for the easy definition of queries by both developers and clients. Due to the fragility of HQL defined queries, a framework allowing for easy definition, multiple formats (Velocity templates, Database values, class files), and transparent lookup is critical.
Lookup happens among all
QuerySources that are registered with the
QueryFactory instance present in OMERO services. The first non-null
Query instance returned by a
QuerySource for a given String id is
Queries implement the
HibernateCallback interface and are passed
directly into an
HibernateTemplate instance. Therefore, care should
be taken as to which
QuerySources are registered with the
Critical for using queries is the specification of named parameters, number of results to return, offset of the first result to return etc. These features are offered by the ome.parameters package. The ome.parameters.Parameters class is the starting point for building new parameters (although the ome.parameters.Filter object is used by some methods).
To specify parameters, instantiate a Parameters object either with or without a Filter object argument. The version with Filter object is useful for specifying the number of results to be returned and whether or not a java.util.Collection or a ome.model.IObject instance will be returned. For example,
Parameters p = new Parameters( new Filter().unique() );
will specify that the given query should return a single instance. An exception will be thrown if more than one result is found.
Parameters p = new Parameters( new Filter().unique().page(0,1) );
However, this will guarantee that only one result will be returned, since more than 1 result (“maxResults”) will be ignored. Here, an ordering of the results might make sense.
Once a Parameters instance is available, named parameters can be added
using any of the
add…() methods. These parameters will be
dynamically bound during query preparation. For example, a query of the
select e from Experimenter e where omeName = :name
has one named parameter “name”, which can be specified by the call:
Positional parameters of the form
select e from Experimenter where omeName = ?
are not supported.
Other than by defining String queries via
new QueryDef() TBD, the
easiest way to create queries is to subclass ome.services.query.Query.
The only non-optional requirements on the Query implementor are then to
define the (possibly optional) named parameters to the Query, and to
override the “buildQuery” (which must call one and only one of
“setQuery()” or “setCriteria()”)
Other than that, the Query implementor can enable filters on the Hibernate session (an attempt is made to clean up after the Query runs), and in general use any of the Hibernate session methods.
Defining a QuerySource
A more involved but perhaps more rewarding method would be to implement
QuerySource and configure
QueryFactory to lookup query ids also
QuerySource. This would allow you to write Velocity (or
QuerySources which use some form
of templating or scripting to generate HQL queries.