There have been inquiries about ability in ADF for declarative databinding a RichTree component to a recursive View Object. A recursive VO is based on a hierarchical "START WITH ... CONNECT BY" SQL clause in Oracle DB, when a table in the schema has a self-referencing foreign key to itself. Such schema design may be used for describing hierarchical organization, or any deeply nested hierarchies.
Solutions have been presented for custom building an ADF RichTree based on a complex hierarchical query. Such examples do not provide declarative databinding, and involve some Java coding.
Providing a lazy loading RichTree with custom Java coding involves lot more complexity, almost building your own custom databinding layer.
A solution is provided here for solving the requirement of a lazy loading RichTree based on self-referencing schema objects. For example, consider a database table SPECS for describing hierarchy of test suites, such that suites may have sub-suites nested upto an indefinite level. Tests are at leaf level in the hierarchy. The column "TYPE" in this table indicates whether a row corresponds to a SUITE or a TEST. The column SUITE_ID is the self referencing foreign key in this table, for referencing a sub-suite or test to its parent suite.
A hierarchical query solution would involve defining a View Object with expert mode SQL query such as below, followed by building a custom TreeModel for this VO and following the solution in AMIS blog link above.
SELECT level, SpecsEO.ID, SpecsEO.TYPE, SpecsEO.DESCRIPTION SpecsEO.SUITE_ID, SpecsEO.WEIGHT, SpecsEO.STATUS FROM SPECS SpecsEO START WITH SpecsEO.SUITE_ID IS NULL CONNECT BY PRIOR SpecsEO.ID = SpecsEO.SUITE_IDThe alternate declarative solution proposed here does away with hierarchical queries altogether. It proposes defining 2 View Objects, a View Object for top level suites (or special case where tests are top level without being contained by any suites), and another View Object for rest of suites or tests. The top level VO breaks the recursion.
TopLevelSpecsVO :
SELECT SpecsEO.ID, SpecsEO.TYPE, SpecsEO.DESCRIPTION, SpecsEO.SUITE_ID, SpecsEO.WEIGHT, SpecsEO.STATUS FROM SPECS SpecsEO WHERE SpecsEO.SUITE_ID IS NULL
SpecsVO :
SELECT SpecsEO.ID, SpecsEO.TYPE, SpecsEO.DESCRIPTION SpecsEO.SUITE_ID, SpecsEO.WEIGHT, SpecsEO.STATUS FROM SPECS SpecsEO
Two View links are defined:
- between TopLevelSpecsVO and SpecsVO (TopLevelSpecsVO.ID = SpecsVO.SUITE_ID)
- between SpecsVO and SpecsVO itself (Source SpecsVO.ID = Destination SpecsVO.SUITE_ID)
When defining databinding for RichTree, simply adding tree level rules based on above view links defines an accessor from view object SpecsVO to itself in the page definition file. This approach automatically takes care of displaying the RichTree with indefinite level of recursion. Apart from being fully declarative, another big advantage of this approach is performance. It provides a lazy loading RichTree by using caching provided by View Object layer.
The strongest advantage of this approach is when a hierarchical object such as this has a descendant relationship with some other object(s), and the RichTree needs to display this relationship through ADF BC backed databinding as well. For example, consider a master-detail relationship between a PRODUCT table and the SPECS table discussed above. Configuring databinding for RichTree between a PRODUCT table based VO and TopLevelSpecsVO would be a trivial exercise, facilitating a RichTree displaying hierarchy from products to test suites all the way down to tests.
To the best of my knowledge, no such declarative solution would be possible were the SPECS VO defined based on a complex hierarchical query, and a TreeModel based on it with a custom managed bean. I spent considerable amount of time investigating such possibility (simply for the sake of being a devil's advocate) and all such attempts were futile. There is simply no way in the current state of the product to mix-and-match ADF BC backed databindings with custom managed bean backed databindings in a declarative fashion. If you think you can prove me wrong, please post in my comments section and let me know how.
The only potential drawback of this approach which I can think of is an increase in the number of configuration objects. For each logical recursive schema object, it doubles the number of View Objects. However in my opinion (especially in the absence of out-of-the-box declarative databinding for a hierarchical object) this is a small price to play, compared to the elegance of a declarative solution with lazy loading.
No comments:
Post a Comment