Monday, March 8, 2010

Cascading LOV in detail view dependent on master view attribute

In some cases we have LOVs in detail view objects that are dependent on an attribute on a master view object.

For example in Departments Employees Master detail, you want to have a list of values for Employees managers to be the department Manager or employees that have the department manager. The LOV query would be :
select *
from employees
where manager_id = :inManager
or employee_id = :inManager

In the view accessor for the LOV you can set the bind variable of the LOV to get value from the master view object ‘DepartmentsView.ManagerId’ or in the employees view object you can add Departments entity and add attribute ManagerId from Departments Entity.

Yet when you change Manager of the Department in both cases the LOV does not know that the bindVariable value has changed and it is still executed with the old value of Department value.

This is happening because the LOV is notified to take new bind value when the setter of the dependent attribute is invoked.

In order to do that I created an updatable transient attribute LOVManagerId that on the getter when it has no internal value it gets the value from Departments entity reference attribute.

public Number getLOVManagerId() {
if (getAttributeInternal(LOVMANAGERID)==null)
return this.getDepartmentManagerId();
return (Number) getAttributeInternal(LOVMANAGERID);
}



Now on the getter of reference entity attribute I check if entity attribute has changed in order to set also the LOVManagerId.

public Number getDepartmentManagerId() {
Number empdepManager = (Number) getAttributeInternal(DEPARTMENTMANAGERID);
if (this.getDepartments().isAttributeChanged("ManagerId"))
this.setLOVManagerId(empdepManager);
return empdepManager;
}

Partial triggers form Department.ManagerId field to Employees table will finish the job.



Test Case :
http://adfbugs.googlecode.com/files/MasterDependentLOV.zip

2 comments:

  1. Hi,

    There is another solution for this, without transient attribute - may be a bit simpler. You can add executeQuery into Bind Variable setter and expose this setter method through Client Interface. Then just invoke it, when you want force new bind variable value propagation.

    Andrejus

    ReplyDelete
  2. Hi,
    I did all the changes in java plus business component , now at the run time the first time i invoked the LOV everything went fine but when i tried to invoke the LOV again i got the following error : target unreachable identifier 'row' resolved to null ..


    any help please

    ReplyDelete