Monday, 21 July 2014

discriminator property in BC4J

On the previous project the data about persons and companies were stored in the same table. There was also a constraint on a column that allows to put 1 for a person and 2 for the company. Moreover, there was a nullable column to store first name, but for the person, the field mustn't be empty. And a lot of similar validations more. It sounds simple to code, but how to achieve this without putting ifs in each validation rule? Solution is also very simple. The main constraint column is the discriminator. And how to code it in ADF? In this post you'll find the abstract example of the discriminator property.

  • we have got already created new fusion application (leave defaults)
  • there is defined one datasource connection to the HR demo schema
  • assumption above indicates that you have got also a local or remote database
During analysis phase the model of the domain defines several independent entities which are extending one base (abstract) entity. They're all stored in the same table in the database. So they inherit validation constraints and these validations are common for each entity. But there is also a set of elements which differs these entities. Some elements are redundant and shouldn't be fulfilled (or fulfilled with defaults), other are mandatory.

Now let us put names to these requirements. A company is divided into departments. In each departments we have got employees, which are stored in EMPLOYEES table. We have got a set of common validation rules, generated from database constraints, such as lastname length validator (max 25 chars). To simplify the example, there are only IT and Sales departments with 1 and 2 value of DEPARTMENT_ID foreign key. Commission percentage value is mandatory for the Sales employees (in database this column is nullable). For IT department commission value couldn't be fulfilled.

First of all we must to create mentioned base (abstract) entity object, so we must to create entity from the EMPLOYEES table. Because the project is new, i've picked option "Business Components from Tables". I've selected only EMPLOYEES table, created entity and editable VO for it. The common validation rules are generated automatically in the entity.

Now the most interesting thing - go to Employees entity and edit DepartmentId attribute. Please check the Discriminator checkbox and put the 2 for Sales department as a default value. To aviod validation problems in the future i've decided to set the updateable attribute to "while new" option.

 Now, after right click on the Emploees entity we can see "Create Extended Object". Click and proceed with the dialog. The example is for the IT employee.

Ok, IT employee is ready to be developed. We must set the discriminator value to 1. To do that the attribute must be overriden. Select DepartmentId, click Override button in the top right corner.

The discriminator attribute checkbox is disabled, but default value isn't. Change it to 1 (IT).

Now the commision attribute. First of all it must be also overriden. It shouldn't be editable, so Updateable option is set to Never. And the default commision value is set to 0.

The SalesEmployeesEx entity is created similar to the IT. Discriminator value is correct, don't change anything there. The commission value is mandatory - override the attribute and check Mandatory option.

There are two child entities based on Employees one. The framework needs to be notified which one should be used. Open EmployeesView view object and go to Entity Object tab. On the right above the selected entities section is Subtypes button.

Please click it and select two child entites created few steps before.

Save all and BC4J model is done.

Create new JSPX test page. Drag and drop the EmployeesView1 from the Data Conrols on the page as form with navigation controls. Select also Commit and Rollback operations to save or cancel the changes.

In page definition of the test page, click green plus icon above the binding section.

Action is already selected, proceed with the dialog. Select an EmployeesView1Iterator and Create with parameters operation from the second list. Change operation id to CreateItEmployee. Right click on the operation, and select Named Data from the Insert inside CreateItEmployee menu. Fulfill the NDName attribute with discriminator attribute name (DepartmentId), oracle.jbo.domain.Number is the NDType of the attribute and 1 is proper NDValue for the IT employee.

Do the same for creating Sales employee operation. Remember about the proper discriminator value.

After that the page definition structure should look like this:

On the JSPX file add two additional buttons to the page and bind them with this operations and change the text attribute to Create IT/Sales employee. Source code of the JSPX file should look more or less like this:

Finally, run the page and check how will it work. Please check differences between Sales and IT employees, how behave CommisionPct attribute.

For the IT ComissionPct is disabled with fixed default value 0.

As a homework i'll suggest to add range validation for salary attribute :)

1 comment: