You can download sample application - ADFBCInheritance.zip where I have implemented inheritance between Entities and created View Object based on polymorphic Entity usage.
I have generated Countries Entity in order to use it as Base Entity in an inheritance hierarchy:
Four Entities - CountriesAfrica, CountriesAmerica, CountriesAsia and CountriesEurope are created as Subtype Entities from Countries Entity in inheritance hierarchy.
While creating Base Entity, I have declared discriminator attribute - RegionId. This attribute will allow us to perform polymorphic queries:
I have left discriminator value as empty by default, this means if View Object will not include any subtype, empty rowset will be returned:
Subtype Entities are created by extending Base Entity and overriding its attributes:
In Subtype Entity we need to set corresponding value for overriden discriminator attribute - RegionId:
For example, in CountriesAfrica Entity I have set this attribute discriminator value to 4:
In CountriesAmerica, CountriesAsia and CountriesEurope it is set to 3, 2 and 1 accordingly. Of course, there is no point to create inheritance hierarchy just for fun, in most of the cases its useful to have it when implementing different validation rules for example. In my sample, I have implemented different validation rules for transient Profit attribute. In CountriesAfrica Entity validation rule is implemented as range between 100 and 1000:
In CountriesAsia Entity, with discriminator value set to 2:
Same type validation rule is implemented with different constraints set to 300 and 1200:
Finally, when View Object is created based on Base Entity - Countries:
You need to include Subtypes of Base Entity you wish to use in your View Object. If you will not include any of Subtypes, View Object will return empty rowset (remember we have set empty default value for discriminator in Base Entity). In my sample, View Object will work with all four Subtypes, so I'm declaring this:
Even my View Object is based on all four Subtypes, I will want to limit rows to expected Enity Subtypes. We can do this, simply by adding discriminator into WHERE clause and declaring Bind Variable, however I have noticed if to implement it in such way - View Accessors from any Detail View Objects will not work. However, everything works fine, if to declare and use View Criteria:
This View Criteria is really simple, it just includes discriminator attribute filtering:
At this point, inheritance in ADF BC Entities is finished. Let's add some more complexity and define association relationship. I will define it between Countries entity with discriminator attribute and Locations:
Based on this association its possible to define Master-Detail relationship through View Link:
Its cool that, you can use Detail View Object - Locations in relationship with Master View Object - Countries just in standard way, even we know that Countries is based on Entity Subtypes. In order to test and prove this, I have created transient attribute in Locations View Object - CountryName. This attribute gets value through accessor from its Master - Countries:
We have following Master-Detail relationship exposed to View-Controller layer:
In View-Controller I have created navigation flow to pass discriminator value into Bounded ADF Task Flow through a call:
In Bounded ADF Task Flow I'm doing ExecuteWithParams in order to set Bind Variable value and opening main page with already filtered values by provided discriminator:
Rowset is pre-filtered by activating View Criteria on page load. View Criteria is activated by referencing Query Model, read more in my previous post - ADF Query Component Usage with ADF Panel Stretch Layout.
On runtime, select any of regions, this will set discriminator value:
Let's select Asia and set Profit value to 350. Remember, CountriesAsia Entity implements validation 300 - 1200, so no error is shown and value is accepted:
Now let's select Europe and set Profit value to the same 350. Remember, CountriesEurope Entity implements validation 400 - 1300, validation error will be shown:
Spanish Summary:
En este post, Andrejus nos entrega un ejemplo de como aplicar mecanismos de herencia entre entidades de Business Components. En una entrega posterior nos mostrará la manera de implementar herencia entre View Objects.