Skip Headers

# Using Redirect Finders

Previous

Next

Redirect finders let you specify a finder in which the implementation is defined as a static method on an arbitrary helper class. When you invoke the finder, it redirects the call to the specified static method.

For more information about redirect queries, see "Redirect Queries".

The finder can have any arbitrary parameters. If the finder includes parameters, TopLink packages them into a `Vector` and passes them to the redirect method.

Redirect finders offer several advantages. Because you define the redirect finder implementation independently from the bean that invokes it, you can build the redirect finder to accept any type and number of parameters. This lets you create a generic redirect finder that accepts several different parameters and return types, depending on input parameters.

A common strategy for using redirect finders is to create a generic finder that does the following:

- Includes logic to perform several tasks

- Reads the first passed parameter to identify the type of finder requested and select the appropriate logic

The redirect method contains the logic required to extract the relevant data from the parameters and uses it to construct a TopLink query.

The main disadvantage of redirect finders is that they are complex and can be difficult to configure. They also require an extra helper method to define the query. However, because they support complex logic, they are often the best choice when you need to implement logic unrelated to the bean on which the redirect method is called.

To create a redirect finder, use the following procedure:

1. Declare the finder in the `ejb-jar.xml` file, and leave the `ejb-ql` tag empty.

2. Declare the finder on the `Home` interface, the `localHome` interface, or both, as required.

3. Create an amendment method.

   For more information, see "Configuring Amendment Methods".

4. Start TopLink Workbench.

5. Choose Advanced Properties > After Load from the menu for the bean.

6. Specify the class and name of the static method to enable the amendment method for the descriptor.

The amendment method then adds a query to the descriptor's query manager, as follows:

    ReadAllQuery query = new ReadAllQuery();
    query.setRedirector(new MethodBaseQueryRedirector (examples.ejb.cmp20.advanced.
      FinderDefinitionHelper.class,"findAllEmployeesByStreetName"));
    descriptor.getQueryManager().addQuery ("findAllEmployeesByStreetName", query);

The redirect method must return either a single entity bean (object) or a `Vector`. Here are the possible method signatures:

    public static Object redirectedQuery(oracle.toplink.sessions.Sessions, Vector args)

and

    public static Vector redirectedQuery(oracle.toplink.sessions.Sessions, Vector args)

When you implement the query method, ensure that the method returns the correct type. For methods that return more than one bean, set the return type to `java.util.Vector`. TopLink converts this result to `java.util.Enumeration` (or Collection) if required.

Note: The redirect method also interprets a TopLink session as a parameter. For more information about a TopLink session, see TopLink Sessions.

At run time, the client invokes the finder from the entity bean home and packages the arguments into the `args` vector in order of appearance from the finder method signature. The client passes the vector to the redirect finder, which uses them to execute a TopLink expression.

A Simple Redirect Query Implementation

    public class RedirectorTest {
        private Session session;
        private Project project;
        public static void main(String args[]) {

           RedirectorTest test = new RedirectorTest();

           test.login();

           try {
                // Create the arguments to be used in the query
                    Vector arguments = new Vector(1);
                    arguments.add("Smith");

                // Run the query
                    Object o = test.getSession()
                    .executeQuery(test.redirectorExample(), arguments);
                    o.toString();
           }
           catch (Exception e) {
                    System.out.println("Exception caught -> " + e);
                    e.printStackTrace();
           }
        }

        public ReadAllQuery redirectorExample() {

           // Create a redirector
           MethodBasedQueryRedirector redirector = new MethodBasedQueryRedirector();

           // Set the class containing the public static method
           redirector.setMethodClass(RedirectorTest.class);

           // Set the name of the method to be run
           redirector.setMethodName("findEmployeeByLastName");

           // Create a query and add the redirector previously created
           ReadAllQuery readAllQuery = new ReadAllQuery(Employee.class);
           readAllQuery.setRedirector(redirector);
           readAllQuery.addArgument("lastName");

           return readAllQuery;
        }

        // Call the static method
        public static Object findEmployeeByLastName(
                               oracle.toplink.sessions.Session session,
                               Vector arguments) {

           // Create a query and set Employee as its ref. class
           ReadAllQuery raq = new ReadAllQuery(Employee.class);
           raq.addArgument("lastName");

           // Create the selection criteria
           ExpressionBuilder employee = query.getExpressionBuilder();
           Expression whereClause =
           employee.get("lastName").equal(arguments.firstElement());

           // Set the selection criteria
           raq.setSelectionCriteria(whereClause);

           return (Vector)session.executeQuery(raq, arguments);
        }
    [...]
    }