Providing Default Values for View Object Bind Variables

Send me a mail
 Dive into Oracle ADF   Click to see the XML version of this web page.   (Updated: 2/3/2008; 9:25:50 PM.)
Tips and tricks from Steve Muench on Oracle ADF Framework and JDeveloper IDE

Providing Default Values for View Object Bind Variables

I wrote up this article in the blog back on Friday, August 1, 2003, but I never can seem to find it when I need to refer to it, so I'm adding it here as a story for easier future reference.

 "How could I program my View Object to provide default values for its bind variables if none has been already supplied programmatically?"

Suppose you have a DeptView with a query like this:

SELECT Dept.DEPTNO, 
       Dept.DNAME,
       Dept.LOC
FROM DEPT Dept
WHERE deptno = :0 and loc = :1

Then, you could override the executeQueryForCollection() method and getQueryHitCount() in your view object implementation class to conditionally default values for these two bind variables using code like this:

  /*
   * Object array of default bind variable values.
   * You could include more elements in this array to default the values
   * of multiple bind variables. In this example, we're supplying default
   * values for the two bind variables in the query.
   */
  private static final Object[] DEFAULT_VALUES = new Object[]{ new Number(10),
                                                        "NEW YORK"};
  private static final int NUM_DEFAULT_VALUES = DEFAULT_VALUES.length;
  /**
   * Overridden framework method to optionally setup default values for
   * all user-supplied bind variables if no user-supplied bind variables
   * have already been set programmatically. If any framework-supplied bind
   * values are already supplied, they will come *AFTER* the "numUserParams"
   * number of user-supplied bind values. Framework-supplied bind variables
   * could be a side-effect of automatic master/detail coordination, for example.
   * @param numUserParams number of user-supplied bind variable parameters
   * @param params array of parameter values
   * @param qc query collection
   */
  protected void executeQueryForCollection(Object qc, Object[] params,
    int numUserParams) {
    /*
     * Assume that we only will default bind variables if NONE has already
     * been specified by the user...
     */
    if (numUserParams == 0) {
      numUserParams = NUM_DEFAULT_VALUES;
      int numFwkSuppliedBindVals = (params != null) ? params.length : 0;
      if (numFwkSuppliedBindVals > 0) {
        /*
         * Allocate a new Object[] with enough room for both the
         * user bind values and the framework supplied bind values
         */
        Object[] newBinds = new Object[numFwkSuppliedBindVals + numUserParams];
        /*
         * Copy the framework-supplied bind variables into a new Object[]
         * leaving 'numUserParams' slots at the beginning of the array to
         * add in the user supplied bind values *before* the framework
         * supplied bind values.
         */
        System.arraycopy(params, 0, newBinds, numUserParams,
          numFwkSuppliedBindVals);
        /*
         * Copy the user-supplied bind variables to the front of the newBinds
         * Object array.
         */
        System.arraycopy(DEFAULT_VALUES, 0, newBinds, 0, numUserParams);
        params = newBinds;
      }
      else {
        params = DEFAULT_VALUES;
      }
      /*
       * It's too late in the execute cycle to use *only* the
       * setWhereClauseParams() to effect the current view object's
       * query execution, but we set them using this API anyway so
       * that they will be remembered on the rowset as the current
       * values for the bind variables. This will insure, for example,
       * that a subsequent call to getEstimatedRowCount() or another API
       * will have the right default bind variables set.
       */
      setWhereClauseParamsToDefaultValues();
    }
    super.executeQueryForCollection(qc, params, numUserParams);
  }
  /**
   * Set this view object's where clause parameters to the
   * default array of parameter values.
   */
  private void setWhereClauseParamsToDefaultValues() {
    setWhereClauseParams(DEFAULT_VALUES);
  }
  /**
   * Overridden framework method that gets invoked when the
   * getEstimatedRowCount() needs to fetch the estimated count
   * from the database.
   * @return estimate of number of rows to be returned by the query
   * @param viewRowSet view row set whose row count is being estimated
   */
  public long getQueryHitCount(ViewRowSetImpl viewRowSet) {
    Object[] whereClauseParams = getWhereClauseParams();
    if ((whereClauseParams == null) || (whereClauseParams.length == 0)) {
      setWhereClauseParams(DEFAULT_VALUES);
    }
    return super.getQueryHitCount(viewRowSet);
  }

I've written the code to work for defaulting any number of initial bind variables, but it has a simplifying assumption that we only default all of the user bind variables, or none (in the case that some were already set programmatically).

If the VO's are involved in View Links, then you need to pay attention to the framework-supplied bind variables that BC4J will tack on to support the extra view link where clause that it will glue on.



© Copyright 2008 Steve Muench. Click here to send an email to the editor of this weblog.
Last update: 2/3/2008; 9:25:50 PM.