About Master-Detail Views

View Links affect the behavior of View Objects within an Application Module. When a View Object is used as the detail end of a master-detail View Link, it selects the restricted view specified by the association that defines the View Link. "Restricted" means that the data from the detail table that is available, depends on a value chosen in the master table.

When it is not involved in a master-detail View Link, a View Object offers an unrestricted view of the data. That is, all rows of data are available. For example, Figure 1 illustrates a situation where a project provides two views, DeptView and EmpView, of the DEPT and EMP tables. For the purposes of an application, you define aliases of the views: MyDeptView, MyEmpDetailView, and MyEmpView. You link MyDeptView and MyEmpDetailView master-detail. In this case, the employee data available from MyEmpDetailView depends on a given value from MyDeptView. For example, it will display only those employee names associated with a given department number.

In MyEmpView, the view is unrestricted: all of the data from the EMP table is available. The original View Objects, DeptView and EmpView, do not participate in the application module.

Figure 1: Application Module using a Master-Detail View and an Unrestricted View

Figure 2 shows MyEmpView operating without restrictions and fetching the specified columns from every row of the EMP table.

Figure 2: Data From an Unrestricted View

In contrast, MyEmpDetailView is the detail end of a View Link. Its result set is restricted by one or more bind values, defined by the attributes of the View Link that occur in MyDeptView. Therefore, it fetches only those rows containing the specified bind values. The View Link is effectively adding a WHERE clause to the SQL statement that defines the View Object. For example, Figure 3 shows MyEmpDetailView being used in the DeptViewToEmpView link. Here, the bind value (defined by MyDeptView's deptno attribute) is 20, so MyEmpDetailView fetches only rows where deptno equals 20. Bind values are provided by the master view.

Figure 3: Data From a Master-Detail (Restricted) View

In summary, a detail View Object in a View Link selects a restricted view of the underlying data based on bind values supplied by the master view. To select an unrestricted view, define a separate View Object in the Application Module. The code example below shows the different behavior of restricted and unrestricted views, and how a detail view depends on the master view for bind values.

package d2e;
import oracle.jbo.*;
public class AliasDemo {
public static void main(String[] args) {
    // Helper routine connects to the generic Application Module.
ApplicationModule appMod =
QueryDemo.getGenericAppMod(JboContext.PLATFORM_LOCAL);
    // Call method to get UnrestrictedView.
ViewObject voEmp = appMod.findViewObject("UnrestrictedEmpView");
printRows(voEmp); // Prints all rows in EMP.
    // Assume DeptView and EmpView were linked
// master-detail at design time.
voEmp = appMod.findViewObject("EmpView"); // Restricted view.
printRows(voEmp); // No master view yet, so no rows printed.
    ViewObject voMaster = appMod.findViewObject("DeptView");
voMaster.first(); // Get bind values from first row of master table.
printRows(voEmp); // Prints restricted view.
}
  public static void printRows(ViewObject vo) {
System.out.println("ViewObject :"+vo.getName()+" - RowCount:"+vo.getRowCount() );
    // Execute the query, print results to the screen.
vo.executeQuery();
while (vo.hasNext()) {
Row row = vo.next();
String rowDataStr = "";
      // How many attributes (columns) is the View Object using?
int numAttrs = vo.getAttributeCount();
      // Column numbers start with 0, not 1.
for (int attrNo = 0; attrNo < numAttrs; attrNo++) {
        // See also Row.getAttribute(String name).
Object attrData = row.getAttribute(attrNo);
rowDataStr += (attrData + "\t");
}
System.out.println(rowDataStr);
}
}
}

About View Links and Events

When two View Objects are linked in a master-detail relationship, the default (or first) iterator for the master View Object fires events to refresh the detail View Object. When the detail View Object is created, the Business Component for Java framework registers it as an event listener for the master's iterator. Thus, when the iterator moves to another row in the master View Object, the contents of the detail View Object are refreshed automatically, as shown in Figure 1.

Figure 1: Changes in a Master View's Iterator Causes a Refresh of Detail View's Contents

The following code example assumes that an Application Module has been defined at design time to include at least one View Link. The code initializes the Application Module, gets the first link, gets the master and detail View Objects from the link, then displays each master row and the linked detail rows.

package d2e;
import oracle.jbo.*;
public class LinkDemo {
public static void main(String[] args) {
    // Helper routine connects to the generic Application Module.
ApplicationModule appMod = QueryDemo.getGenericAppMod(JboContext.PLATFORM_LOCAL);
    // Get the first link defined in the Application Module.
String[] linkNames = appMod.getViewLinkNames();
if (linkNames.length < 1) {
System.out.println("\n No links.");
return;
}
    ViewLink link = appMod.findViewLink(linkNames[0]);
    // Get View Objects defined in the link.
ViewObject voMaster = link.getSource();
ViewObject voDetail = link.getDestination();
    // Execute query and move through the master rows.
voMaster.executeQuery();
while (voMaster.hasNext()) {
printRow(voMaster.next());
      // JDeveloper automatically refreshes the detail result set.
// Move through linked detail rows.
while (voDetail.hasNext()) {
printRow(voDetail.next());
}
}
}
  // This is a helper method that prints data to the screen.
public static void printRow(Row row) {
String rowAttrs = "";
for (int i = 0; i < row.getAttributeCount(); i++) {
rowAttrs += (row.getAttribute(i) + "\t");
}
System.out.println(rowAttrs);
}
}

Figure 2 shows the event flow between master and detail View Objects. When you define a link, the Business Components for Java framework registers the detail View Object to listen for events from the corresponding master View Object.  When the current row in the master View Object changes, the framework fires an event and the detail View Object responds by refreshing the detail View Object. This action in turn fires another event, which can be handled by registered listeners, if any.

Figure 2: Event Flow Between Master and Detail View Objects