5.  MethodQL

If JPQL and SQL queries do not match your needs, OpenJPA also allows you to name a Java method to use to load a set of objects. In a MethodQL query, the query string names a static method to invoke to determine the matching objects:

import org.apache.openjpa.persistence.*;

...

// the method query language is 'openjpa.MethodQL'.
// set the query string to the target method to execute, prefixed by fullly-
// qualified class name.
// If a candidate class has been specified for the query, then if the class is 
// in the candidate class' package or in the query imports, you can omit the 
// package. If the method is in the candidate class, you can omit the class name 
// and just specify the method name.

  OpenJPAEntityManager oem = OpenJPAPersistence.cast(emf);
  OpenJPAQuery q = oem.createQuery("openjpa.MethodQL", "com.xyz.Finder.getByName");

// parameters are passed the same way as in standard queries
// but you have to declare the parameters with their types on the implementation

// Unwrap the implementation and declare parameters with types in a 
// comma-separated list
  q.unwrap(org.apache.openjpa.kernel.Query.class)
   .declareParameters("String firstName, String lastName");

  q.setParameter("firstName", "Fred").setParameter("lastName", "Lucas");

// this executes the target method to get the results
  List results = q.getResultList();

// The result is returned as a list but the element(s) in the list is determined 
// by the returned value of the target method
 

For datastore queries, the method must have the following signature:

public static ResultObjectProvider xxx(StoreContext ctx, ClassMetaData meta, boolean subclasses, Map params, FetchConfiguration  fetch)

The returned result object provider should produce objects of the candidate class that match the method's search criteria. If the returned objects do not have all fields in the given fetch configuration loaded, OpenJPA will make additional trips to the datastore as necessary to fill in the data for the missing fields.

In-memory execution is slightly different, taking in one object at a time and returning a boolean on whether the object matches the query:

public static boolean xxx(StoreContext ctx, ClassMetaData meta, boolean subclasses, Object obj, Map params, FetchConfiguration fetch)

In both method versions, the given params map contains the names and values of all the parameters for the query.