Using a method validator based on a view object accessor

In this recipe, we will show how to validate an entity object against a view accessor using a custom entity method validator. The use case that we will cover—based on the HR schema—will not allow the user to enter more than a specified number of employees per department.

Getting ready

We will be using the HRComponents workspace that we created in the previous recipes in this chapter so that we don't repeat these steps again. You will need access to the HR database schema.

How to do it…

  1. Right-click on the com.packt.jdeveloper.cookbook.hr.components.model.view package of the HRComponentsBC business components project of the HRComponents workspace, and select New View Object….
  2. Use the Create View Object wizard to create a SQL query view object called EmployeeCount based on the following query:
    SELECT COUNT(*) AS EMPLOYEE_COUNT FROM EMPLOYEES WHERE DEPARTMENT_ID = :DepartmentId
  3. While on the Create View Object wizard, also do the following:
    • Create a Bind Variable called DepartmentId of type Number
    • On the Attribute Settings page, ensure that you select Key Attribute for the EmployeeCount attribute
    • On the Java page make sure that both the Generate View Row Class and Include accessors checkboxes are checked
    • Do not add the view object to an application module
  4. Now, double-click on the Employee entity object to open its definition and go to the View Accessors page.
  5. Click on the Create new view accessors button (the green plus sign icon) to bring up the View Accessors dialog.
  6. On the View Accessors dialog locate the EmployeeCount view object and click the Add instance button—the blue right arrow button. Click OK to dismiss the dialog.
    How to do it…
  7. On the entity object definition Business Rules tab, select the Employee entity and click on the Create new validator button (the green plus sign icon).
  8. On the Add Validation Rule dialog, select Method for the Rule Type and enter validateDepartmentEmployeeCount for the Method Name.
  9. Click on the Failure Handling tab and in the Message Text enter the message Department has reached maximum employee limit. Click OK.
  10. Open the EmployeeImpl custom implementation Java class, locate the validateDepartmentEmployeeCount() method and add the following code to it before the return true statement:
    // get the EmployeeCount view accessor
    RowSet employeeCount = this.getEmployeeCount();
    // setup the DepartmentId bind variable
    employeeCount.setNamedWhereClauseParam("DepartmentId",this.getDepartmentId());
    // run the View Object query
    employeeCount.executeQuery();
    // check results
    if (employeeCount.hasNext()) {
      // get the EmployeeCount row
      EmployeeCountRowImpl employeeCountRow =(EmployeeCountRowImpl)employeeCount.next();
      // get the deparment employee count
      Number departmentEmployees = employeeCountRow.getEmployeeCount();
      if (departmentEmployees.compareTo(MAX_DEPARTMENT_EMPLOYEES)>0) {
        return false;
      }
    }

How it works...

We have created a separate query-based view object called EmployeeCount for validation purposes. If you look closely at the EmployeeCount query, you will see that it determines the number of employees in a department. Which department is determined by the bind variable DepartmentId used in the WHERE clause of the query.

We then add the EmployeeCount view object as a view accessor to the Employee object. We call the accessor instance EmployeeCount as well. Once you have generated a custom Java implementation class for the Employee entity object, the EmployeeCount view accessor is available by calling getEmployeeCount().

We proceed by adding a method validator to the entity object. We call the method to use for the validator validateDepartmentEmployeeCount. JDeveloper created this method for us in the entity custom implementation Java class.

The code that we add to the validateDepartmentEmployeeCount() method first gets the EmployeeCount accessor, and calls setNamedWhereClauseParam() on it to set the value of the DepartmentId bind variable to the value of the department identifier from the current Employee. This value is accessible via the getDepartmentId() method. We then execute the EmployeeCount view object query by calling its executeQuery() method. We check for the results of the query by calling hasNext() on the view object. If the query yields results, we get the next result row by calling next() . We have casted the oracle.job.Row returned by next() to an EmployeeCountRowImpl so we can directly call its getEmployeeCount() accessor. This returns the number of employees for the specific department. We then compare it to a predefined maximum number of employees per department identified by the constant MAX_DEPARTMENT_EMPLOYEES .

The method validator returns a false to indicate that the validation will fail. Otherwise it returns true.

Observe what happens when you run the application module with the ADF Model Tester. When you try to add a new employee to a department that has more than a predefined number of employees (identified by the constant MAX_DEPARTMENT_EMPLOYEES), a validation message is raised. This is the message that we defined for our method validator.

How it works...

There's more...

Note that in the previous code we called setNamedWhereClauseParam() on the EmployeeCount view object to set the value of the DepartmentId bind variable to the current employee's department ID. This could have been done declaratively as well using the Edit View Accessor dialog, which is available on the View Accessors page of the Employee entity definition page by clicking on the Edit selected View Accessor button (the pen icon). On the Edit View Accessor dialog, locate the DepartmentId bind variable in the Bind Parameter Values section, and on the Value field enter DepartmentId. This will set the value of the DepartmentId bind variable to the value of the DepartmentId attribute of the Employee entity object.

There's more...

See also

  • Overriding remove() to delete associated children entities, in this chapter