Follow by Email

Friday, 27 September 2013

Refreshing Child Nodes of an af:treeTable / af:tree in Oracle ADF

Hello All,
A very common problem in ADF treeTable and tree is to refresh child nodes after any DML operation on tree.
to avoid this refresh problem developer can pragmatically refresh treeTable's child node.


  • First get the master ViewObject on that treeTable is based
  • if viewObject has any key attribute then filter it against a key for that you want to refresh child nodes
  • if viewObject doesn't have any key attribute, then filter it using any unique key to get header(master) row
  • get the rowset of child rows for that key, using viewlink accessor
  • and execute query for Child Rows rowset
  • see the refreshed child node :-)

Code- Using Key Attribute


// Get Master ViewObject
    ViewObjectImpl viewObj = masterViewObject;  
    // Filter It Using Key Attribute
  Row[] grpRow = vo.findByKey(new Key(new Object[] { keyAttribute Value }), 1);  
       // Get Child Rows using ViewLink Accessor
        if(grpRow.length>0){
        RowSet childRows = (RowSet)grpRow[0].getAttribute("viewLink AccessorName");  
  //Execute Child Rowset
        childRows.executeQuery();  
        }

Using Unique Key






      // Get Master ViewObject
    ViewObjectImpl viewObj = masterViewObject;  
    // Filter It Using Key Attribute
   Row[] grpRow=viewObj.getFilteredRows("uniqueKey", uniqueKey Value); 
       // Get Child Rows using ViewLink Accessor
        if(grpRow.length>0){
        RowSet childRows = (RowSet)grpRow[0].getAttribute("viewLink AccessorName");  
  //Execute Child Rowset
        childRows.executeQuery();  
        }
  

Somo more blogs on tree table
Programmatically refreshing the child nodes of an <af:tree>
Tree Table Component in Oracle ADF(Hierarchical Representation)
Implementing master/detail tree relation using af:Iterator and af:forEach for better UI designs - Oracle ADF 
Tree Table Component with declarative presentation in ADF, Access childs without custom selection listener
CRUD operations on a tree table
Tree Table Component in Oracle ADF

Cheers :-)

Monday, 23 September 2013

Dynamically enable or disable items of ADF bound List (af:selectOneChoice) -Oracle ADF

Hello All,
This tutorial is about a requirement of conditionally enabling/disabling items (values) of adf bound List (af:selectOneChoice) component
here i am taking reference of default HR Schema (Departments and Location table )

See the steps-
  • Create a Fusion Web Application and business components using both tables
  •  Now create List of Values (Lov) on locationId of departments VO from Location VO
  • Set List Attribute to LocationId and for UI city will be shown
  • Now Drag Departments VO from Data Control on page as a form
  •  Select LocationId list field and delete f:selectItems from it, now drag af:selectItem as child of af:selectOneChoice and surround it with af:forEach 



  • Add tree binding of Location ViewObject to page bindings in order to populate list items using forEach
  •  Now select af:forEach and set its property and variable name, as we have to iterate through Location VO for list items
  •  Again select af:selectItem and set its value and label property using forEach variable's  
  • Now run your application, and see that list box is ready with values
  • Now we have to disable its values as a condition basis, i have written an Expression on af:selectItem's disabled property


  • I have written condition for DepartmentId 100 and 110, see in source of page

  • <af:selectOneChoice value="#{bindings.LocationId.inputValue}" label="#{bindings.LocationId.label}"
                                            required="#{bindings.LocationId.hints.mandatory}"
                                            shortDesc="#{bindings.LocationId.hints.tooltip}" id="soc1"
                                            contentStyle="width:150px;color:red;">
                            <af:forEach items="#{bindings.Locations1.rangeSet}" var="list">
                                <af:selectItem label="#{list.City}" id="si1" value="#{list.LocationId}"
                                               disabled="#{ (bindings.DepartmentId.inputValue==100 and (list.LocationId==1000 || list.LocationId==1300)) || (bindings.DepartmentId.inputValue==110 and (list.LocationId==1500 || list.LocationId==1600 || list.LocationId==1700 || list.LocationId==1800 || list.LocationId==1900))}"/>
                            </af:forEach>
                        </af:selectOneChoice>
    

  • Now value given in Expression for Location Id will be disabled for given Department
  • Run your page and select DepartmentId 100 and 110 to see disabled list items

 Download Sample App Cheers :-)

Thursday, 19 September 2013

Adding Drag and Drop Functionality for collections in page fragments to create insert

Hello All,
This tutorial is based on using Drag & Drop functionality in collections as af:table to create a new row
i have googled about Drag & Drop but was not able to implement in page fragments(.jsff), all samples was based on JSPX page.

this tutorial is based on DEPARTMENTS table (Default HR Schema) and an other table with Same Structure DEPARTMENTS_DUPL to implement drag and drop.
my scenario is to add row in DEPARTMENTS_DUPL from Departments 
 See the steps to implement- 
  •  First create Departments_dupl table in your HR schema, simply run this script

  • CREATE TABLE DEPARTMENTS_DUPL
      (
        DEPARTMENT_ID   NUMBER(4, 0) ,
        DEPARTMENT_NAME VARCHAR2(30 BYTE) ,
        MANAGER_ID      NUMBER(6, 0) ,
        LOCATION_ID     NUMBER(4, 0)
      )
    

  • Now create Fusion Web Application and create business components
  • Now create a bounded taskflow and a page fragment in it, and drop both tables on page

  • Now drop af:dragSource as child of Departments table and set properties, here discriminant is to ensure compatibility between drag and drop components, and its value must match for Drag source and Drop Target


  • now drop af:dropTarget as child of DepartmentsDupl table and set properties as Action etc and create a DropListener for it that handles drop event, set Flavor class to java.lang.Object





  • Now select af:dropTarget and goto source and set value for discriminant same as drag source

  •   <af:dropTarget dropListener="#{pageFlowScope.DragDropSampleBean.deptDropListener}" actions="COPY">
              <af:dataFlavor discriminant="copyDept" flavorClass="java.lang.Object"/>
            </af:dropTarget>
    



  • Now write code to create a new row in DepartmentsDupl and insert data from Departments on Drop Listener


  •     public void dragDropAction() {
            ViewObject dept = this.getDepartments1();
            ViewObject deptDupl = this.getDepartmentsDupl1();
            Row curDept = dept.getCurrentRow();
         
            Row dupl = deptDupl.createRow();
            dupl.setAttribute("DepartmentId", curDept.getAttribute("DepartmentId"));
            dupl.setAttribute("DepartmentName", curDept.getAttribute("DepartmentName"));
            dupl.setAttribute("ManagerId", curDept.getAttribute("ManagerId"));
            dupl.setAttribute("LocationId", curDept.getAttribute("LocationId"));
            deptDupl.insertRow(dupl);
            deptDupl.executeQuery();
            this.getDBTransaction().commit();
        }
    

  • Now Run your page and use this cool functionality :-)
 Download Sample App Cheers :-)

Wednesday, 18 September 2013

Using af:switcher in ADF Faces to dynamically render page components

Hello all,,
Sometimes we need to display page components on a condition basis , this can be achieved in adf using af:switcher component
Normally switcher component is a collection of multiple facets and on a given condition it decides that which facet should be rendered.

How to use af:switcher- see the steps

  • Create a Fusion web application and create business components using Departments and Employees table (HR Schema)
  •  Now create a page in view Controller and drop a switcher component from component palette
  • Switcher is pure server side component so it doesn't have any client representation, so next move is to add facets in af:switcher, to add facets in switcher,
    just right click--insert inside af:switcher-- facet



  • As in this tutorial i am going to show 2 tables(Departments U& Employees) so added 2 facets in af:switcher

  • Now time to drop tables in corresponding facets, Employees Table in Emp, Departments Table in Dept
  •  Now i have created a static List that has values D for Departments and E for Employees, when user selects D the Departments table will be shown and for E Employees table will be shown

  • to do this select af:switcher and go to FacetName property and open expression builder to write conditional expression
  •  Now run this page and select values in list to see- how switcher works

  Download Sample App Cheers :-)

Tuesday, 17 September 2013

Bug in ADF 11g R2- Transient and Bind Valiable of Timestamp type

This is a bug in ADF 11g R2, and sometimes so much annoying for developer.

Bug Is-

  • Suppose you have created business components for Employees table of HR Schema, there is HireDate in Employees table , see it in EntityObject-

  • Now go to source and see, it is of type oracle.jbo.domain.Timestamp (default java representation of Timestamp database data type )

  • Now go to Employees ViewObject and create a transient variable for DOB(Date Of Birth)  and select it as Timestamp
  •  Now after this if developer tries to get or set value of this transient variable, it shows a exception (java.sql.Timestamp can not be cast to oracle.jbo.domain.Timestamp)



  •  To solve this error go to Employees ViewObject and select transient attribute and go to source, se it is of type java.sql.Timestamp

  • Change it to oracle.jbo.domain.Timestamp  and then run it
  • So this is a bug when developer creates new Transient or Query bind variables of Timestamp type, ADF automatically assign it java.sql.Timestamp
Always check it when using Jdveloper 11gR2

Cheers... happy debugging

Friday, 13 September 2013

Using af:inputNumberSlider and af:inputRangeSlider for good UI in Oracle ADF

Hello All,
This tutorial is about slider component
Slider is cool and interesting component in ADF to select a single number or to select a range
there is two types of slider available in ADF Faces

1. af:inputNumberSlider (to select single value)
2. af:inputRangeSlider (to select range)

Follow steps to learn how to use slider in ADF
  • Go to Component Palette and search slider and drop it  into page
  • look in property inspector of slider , there are many properties to customise this component, you can change min-max values,orientation etc

  •  See Horizontal and Vertical slider-

  • Now to get its value in bean , bind both slider to managed bean, using binding property



  •     private RichInputNumberSlider numberSliderBind;
        private RichInputRangeSlider rangeSliderBind;
    
    
        public void setNumberSliderBind(RichInputNumberSlider numberSliderBind) {
            this.numberSliderBind = numberSliderBind;
        }
    
        public RichInputNumberSlider getNumberSliderBind() {
            return numberSliderBind;
        }
    
        public void setRangeSliderBind(RichInputRangeSlider rangeSliderBind) {
            this.rangeSliderBind = rangeSliderBind;
        }
    
        public RichInputRangeSlider getRangeSliderBind() {
            return rangeSliderBind;
        }
    

  • now to get value of inputNumberSlider simply use binding.getValue()

  •  Number numberVal = (Number)numberSliderBind.getValue();
    

  • To get Range of inputRangeSlider use this

  •         NumberRange sliderVal = (NumberRange)getRangeSliderBind().getValue();
            Number minVal=sliderVal.getMinimum();
            Number maxVal=sliderVal.getMaximum();
    

  • Now Run your page and see how is it-
You can use slider for custom search, fixed range interval etc

Tuesday, 3 September 2013

Avoiding JBO-27101: DeadEntityAccessException, Attempt to access dead entity -Oracle ADF


JBO-27101-DeadEntityAccessException
As Per Oracle docs- JBO-27101: DeadEntityAccessException

Cause: Trying to refer to an invalid/obsolete entity. This could occur if some business logic has held on to an entity reference which was removed and the transaction has been posted or committed. It could also occur if a reference entity has been removed from the cache and any ViewRow is attempting to access it.

Action: Use findByPrimaryKey to find a valid entity of the desired key instead of holding on to a reference to an entity instance.


oracle.jbo.DeadEntityAccessException: JBO-27101: Attempt to access dead entity in DepartmentsEO, key=oracle.jbo.Key[10 ]
 at oracle.jbo.server.EntityImpl.setAttributeValueInternal(EntityImpl.java:3649)
 at oracle.jbo.server.EntityImpl.setAttributeValue(EntityImpl.java:3599)
 at oracle.jbo.server.AttributeDefImpl.set(AttributeDefImpl.java:3193)
 at oracle.jbo.server.EntityImpl.setAttributeInternal(EntityImpl.java:1936)
 at exception.model.entities.DepartmentsEOImpl.setManagerId(DepartmentsEOImpl.java:142)
 at exception.model.entities.DepartmentsEOImpl.doDML(DepartmentsEOImpl.java:229)
 at oracle.jbo.server.EntityImpl.postChanges(EntityImpl.java:6721)
 at oracle.jbo.server.DBTransactionImpl.doPostTransactionListeners(DBTransactionImpl.java:3264)
 at oracle.jbo.server.DBTransactionImpl.postChanges(DBTransactionImpl.java:3067)
 at oracle.jbo.server.DBTransactionImpl.commitInternal(DBTransactionImpl.java:2071)
 at oracle.jbo.server.DBTransactionImpl.commit(DBTransactionImpl.java:2352)
 at oracle.adf.model.bc4j.DCJboDataControl.commitTransaction(DCJboDataControl.java:1590)
 at oracle.adf.model.binding.DCDataControl.callCommitTransaction(DCDataControl.java:1415)
 at oracle.jbo.uicli.binding.JUCtrlActionBinding.doIt(JUCtrlActionBinding.java:1428)
 at oracle.adf.model.binding.DCDataControl.invokeOperation(DCDataControl.java:2169)
 at oracle.jbo.uicli.binding.JUCtrlActionBinding.invoke(JUCtrlActionBinding.java:731)
 at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.executeEvent(PageLifecycleImpl.java:402)
 at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding._execute(FacesCtrlActionBinding.java:252)
 at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding.execute(FacesCtrlActionBinding.java:185)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.sun.el.parser.AstValue.invoke(Unknown Source)
 at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)

This exception mainly occurs when developer/User removes a row from ViewObject and try to access it again to set any value or to commit transaction .
if entity(object of a row in table) is removed and then accessed from cache throws this exception
So Always check code that you have written to remove a row from entity and do check your doDML() method in EntityImpl class as it executes during commit after any DML Operation (Update, Delete).

Steps to reproduce DeadEntityAccessException-
  • here i am using default HR Schema (Departments table)
  • Create business components using Departments table

  • create a page and drag Departments viewObject from data control as a table on page and also drop delete and commit operation on page
  • Now go to EOImpl class of Departments Entity Object and just set any attribute's value in doDML(); method

  •     /**
         * Custom DML update/insert/delete logic here.
         * @param operation the operation type
         * @param e the transaction event
         */
        protected void doDML(int operation, TransactionEvent e) {
            setManagerId(1800);
            super.doDML(operation, e);
        }
    
  • Now just run your application and delete any row then press commit, in this case doDML(); method try to set managerId in deleted row that is not in cache, in this case you will see DeadEntityAccessException