Weird ADF 11g requirement addressed with left outer join and modern SQL join syntax
The functional requirement was a little unusual. The page should either show all master-records or – depending on the value of a parameter – it should show exactly one master-record joined with exactly one detail-record. The use case was valid – that was exactly the functionality that was required.
In terms of EMP and DEPT -I like to always simplify things to express them in EMP and DEPT terms – , we should either see all Departments (and no Employee data) or we should see the data for a specific Employee joined with the data for its corresponding Department. And of course we just one to create a single page, and make it as simple as possible to create that page.
A simplistic page that supports this functionality could like this:
when a specific Employee is requested and
when all Departments should be shown, because no single Employee is asked for.
The trick to easily deal with this challenge is not in the View but in the Model – and more specifically in the SQL that powers the underlying ViewObject. By making clever use of the ‘new’ (introduced in Oracle 9i in 2001 (!)) join syntax in SQL that gives us new functionality as well as the new syntax, it turns out to be quite simple to create a single ViewObject that queries either one joined record or multiple unjoined-records.
The steps to reproduce:
1. Create a JDeveloper Fusion Web Application. Create a Database Connection to SCOTT schema.
2. Create (default) Entity Objects on EMP and DEPT. Create an updateable ViewObject DepartmentsView on DEPT
Edit the ViewObject DepartmentsView
3. Add a Bind Variable with name bind_empno and of type Integer:
4. Edit the Query for the View Object
Set the Query Mode to Expert:
Edit the FROM and WHERE section of the query:
What the query now means is:
- get all Departments
- outer join these Departments – meaning that all Departments will live through this join step, even those that cannot be joined – to Employee whenever possible, based on two conditions:
- 1. the value of deptno in Department should match the value of deptno in Employee
- 2. the value of empno in Employee should match the value of the :bind_empno bind variable
- from the result – which always includes at least four Department records and possibly fifteen records (one for Department 40 and 14 for the Employees and their join with a Department) – filter all records that do not have the proper empno value (that is, when the bind variable has a value; when it does not, all records are allowed)
The join condition will not allow through any Employee records when the bind variable is NULL. In that case, all four Department records are returned because of the left outer join. When the bind variable is not null, only the Employee with that value in its empno attribute will survive the join, together with its associated Department – and along with the other three departments because of the outer join. Those three departments should be filtered out in the case of a value in bind_empno and that is what the WHERE clause takes care of.
5. Run the Application Module to see the ViewObject in action:
The tester appears. Double click the ViewObject.
Enter no value for bind_empno, just click on OK.
The departments are all shown – without associated Employee details.
Press the refresh icon. Re-click the ViewObject and this time type a value for the bind_empno variable, the EMPNO value for an existing Employee:
Now only a single record is returned. It consists of the selected Employee joined with the associated Department.
6. Create and run the Web Page
Creating the page is trivial now – the smartness is all in the ViewObject and really in the SQL.
After dragging the ViewObject based collection as a Form, also drag the ExecuteWithParams method as a parameter form:
Now run the page.
Without a value for the bind variable, all Departments are shown -without any employee details.
Enter a value for the bind_empno variable and press the ExecuteWithParams button. The details for Employee 7934 appear along with the associated Department.
Download the JDeveloper application (126.96.36.199): AllDeptsOrOneEmpPlusDept_OuterJoinedVO.
- Summary results for all dates, including the ones that I do not have data for – example of using Partition Outer Join – Oracle10g SQL Feature
- Anti-Search patterns – SQL to look for what is NOT there – Part One
- Writing tables to xml
- ADF 11g – TreeTable with sub totals – how the SQL query can make life easier for the View developer
- ADF: The best way to indicate for records in a table the existence of details – or: the importance of up-to-date SQL knowledge
- Oracle ADF Virtual Developer Day 2013
- The AMIS Summary of Oracle OpenWorld 2013 is available for download – 60-page white paper
- On the integrity of data in Java applications – presentation from JFall 2013
- Enriching XMLType data using relational data – XQuery and fn:collection in action
- Java 8 – Collection enhancements leveraging Lambda Expressions – or: How Java emulates SQL
- OOW13: summarizing one week and 2000 sessions in 3 hours and a bit – the yearly AMIS OOW Review session – 10th October
- Case Study: A Case of Fusion Middleware
- Het Oracle OpenWorld Preview Evenement (5 september 2013) – 15 sprekers & sessies
- ADF 12c: Using WebSockets to implement client to client push (in a scalable manner)
- ADF 12c – The Hierarchical Mystery Tour – Treemap, Sunburst, Treetable, Hierarchy Viewer and Thematic Map