Monday, May 14, 2012

EJB DataControl - programmatically construct Master-Detail hierarchy

Sometimes, in EJB data control it is necessary to construct Master-Detail relationships across different levels pro-grammatically. One of the most common use cases is construct the master-detail relation based on database tables where tables doesn't have foreign key relationship. So in this article, I'm trying to construct master-detail hierarchy pro-grammatically by taking simple custom_dept, custom_emp tables.

You can download the sample workspace from here
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

Note:- In Bean Data Control, Master-Detail hierarchy can be constructed as a same way but  java bean classes to be created first and then pro-grammatically populate the data in session facade.

Model Diagram:



Implementation Steps

Create Java EE Web Application with entities based on custom_dept and custom_emp tables, then create a session bean and data control for the session bean. Open cusotm_dept entity and create a transient variable called "empCollection" and add the below code.
@Transient
private Collection empCollection = new ArrayList();

public void setEmpCollection(Collection empCollection) {
   this.empCollection = empCollection;
}

public Collection getEmpCollection() {
   return empCollection;
}

Open session facade, add the below code to the session facade and expose the masterDetailFindAll() method in local/remote interface and generate a data control for that.

Note:- Here in the below code "em" is a EntityManager.
public List masterDetailFindAll() {
String deptQueryString = "select * from custom_dept";
Query deptSearchQuery = em.createNativeQuery(deptQueryString, "deptQuery");
List deptResultList = deptSearchQuery.getResultList();
Iterator deptListIterator = deptResultList.iterator();
List deptList = new ArrayList();
while (deptListIterator.hasNext()) {
     Object deptCol[] = (Object[])deptListIterator.next();
     CustomDept dept = new CustomDept();
     BigDecimal departmentId = (BigDecimal)deptCol[0];
     dept.setDepartmentId(departmentId);
     dept.setDepartmentName((String)deptCol[1]);
     dept.setLocationId((BigDecimal)deptCol[2]);
     String empQueryString =
       "select * from custom_emp emp, custom_dept dept where emp.department_id = dept.department_id and dept.department_id = " +
     departmentId;
     Query empSearchQuery = em.createNativeQuery(empQueryString, "empQuery");
     List empResultList = empSearchQuery.getResultList();
     Iterator empListIterator = empResultList.iterator();
     List empList = new ArrayList();
     while (empListIterator.hasNext()) {
          Object empCol[] = (Object[])empListIterator.next();
          CustomEmp emp = new CustomEmp();
          emp.setEmployeeId((BigDecimal)empCol[0]);
          emp.setFirstName((String)empCol[1]);
          emp.setLastName((String)empCol[2]);
          emp.setEmail((String)empCol[3]);
          emp.setJobId((String)empCol[4]);
          emp.setDepartmentId((BigDecimal)empCol[5]);
          empList.add(emp);
     }
     dept.setEmpCollection(empList);
     deptList.add(dept);
 }
  return deptList;
}

In the ViewController create index.jspx page, from data control palette drag and drop masterDetailFindAll()->CustomDept->empCollection->Master-Detail as ADF Master Form, Detail Table.

Run the index.jspx page, now we can traverse through Master-Detail records.


No comments:

Post a Comment