Please disable your adblock and script blockers to view this page

Search this blog

Monday 1 July 2013

Update Model Values while Validation (Exception) occurs on page on Value Change event- Oracle ADF (processUpdates)

In ADF when we have some validation on page and we try to submit any value, but normally after validation (Exception) values are not updated in Model until exception is handled.
This tutorial is about how to update values in Model while exception on page.
For a scenario, i have used department (default HR Schema) table and form in a JSP XML fragment inside bounded taskflow.
In form Department Id and Department Name is mandatory field, ManagerId and Location Id has auto submit true.
  • I have dropped createInsert,Execute,Commit and Rollback as buttons on page




  • Click on create button and first enter manager id, as this field has autosubmit true so on submission of value page is validated and then Required Fields throw exception, and after exception you can see that manager id & location id is not updated in Model, and not reflected in af:table also.


  •  Normally what we do, set immediate true to skip validations, but in this case i have witten ValueChangeListener on manager Id and Location Id to process values in Model.- see code

  •     public void mangrIdVCE(ValueChangeEvent vce) {
            vce.getComponent().processUpdates(FacesContext.getCurrentInstance());
        }
    

  • processUpdates() method of UIComponent class perform the coponent tree processing for all facet of this component by Update Model Values phase of request processing, and pushes data to Model

  • Now after calling this method, run application- Now values are populated in af:table and validation is still there on page


  • this approach can be used while using validators on page and want to process some values after validation (as conditional validation of some fields etc)
  • Download sample application -Sample App

Saturday 29 June 2013

Target Unreachable -identifier 'row' resolved to null ADF_FACES-60097- Oracle ADF

"row resolved to null" in ADF Faces- is one of the most harassing bug , and still there is no proper reason or solution for it.
recently i was working in an ADF application and this error occurs. I was not able to find root cause . see this crash-

and log on console-


<LifecycleImpl> <_handleException> ADF_FACES-60098:Faces lifecycle receives unhandled exceptions in phase APPLY_REQUEST_VALUES 2
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'row' resolved to null
 at com.sun.el.parser.AstValue.getTarget(Unknown Source)
 at com.sun.el.parser.AstValue.isReadOnly(Unknown Source)
 at com.sun.el.ValueExpressionImpl.isReadOnly(Unknown Source)
 at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer._getUncachedReadOnly(EditableValueRenderer.java:476)
 at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.getReadOnly(EditableValueRenderer.java:390)
 at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.wasSubmitted(EditableValueRenderer.java:345)
 at oracle.adfinternal.view.faces.renderkit.rich.EditableValueRenderer.decodeInternal(EditableValueRenderer.java:116)
 at oracle.adfinternal.view.faces.renderkit.rich.SimpleInputDateRenderer.decodeInternal(SimpleInputDateRenderer.java:72)
 at oracle.adfinternal.view.faces.renderkit.rich.LabeledInputRenderer.decodeInternal(LabeledInputRenderer.java:56)
 at oracle.adf.view.rich.render.RichRenderer.decode(RichRenderer.java:342)
 at org.apache.myfaces.trinidad.render.CoreRenderer.decode(CoreRenderer.java:292)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.__rendererDecode(UIXComponentBase.java:1334)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.decode(UIXComponentBase.java:865)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.processDecodes(UIXComponentBase.java:965)
 at org.apache.myfaces.trinidad.component.UIXEditableValue.processDecodes(UIXEditableValue.java:287)
 at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl$ApplyRequestValuesCallback.invokeContextCallback(LifecycleImpl.java:1548)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1735)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1750)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXCollection.invokeOnComponent(UIXCollection.java:1215)
 at oracle.adf.view.rich.component.rich.data.RichTable.invokeOnComponent(RichTable.java:620)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1750)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1750)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnNamingContainerComponent(UIXComponentBase.java:1693)
 at oracle.adf.view.rich.component.fragment.UIXRegion.invokeOnComponent(UIXRegion.java:625)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1750)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:1627)
 at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:1750)
 at org.apache.myfaces.trinidad.component.UIXDocument.invokeOnComponent(UIXDocument.java:106)
 at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1299)
 at javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:677)
 at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:374)
 at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:204)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
 at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
 at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
 at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:173)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:122)
 at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:468)
 at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
 at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:468)
 at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:293)
 at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:199)
 at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:180)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)
 at java.security.AccessController.doPrivileged(Native Method)
 at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)
 at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)
 at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)
 at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)
 at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
 at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
 at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
 at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
<RegistrationConfigurator> <handleError> ADF_FACES-60096:Server Exception during PPR, #1
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'row' resolved to null 


after lot of probing- finally i have fixed it, and sharing same .

Possible Causes-
  • Mainly occurs in editable af:table
  • Problem with Primary Key
  • af:column's component's property is being used in any EL, inside or outside of table
        Exp- #{row.bindings.xyz.inputValue==0} 
  • Updateable primary key, and autosubmit true




Possible Solution -
  • Never use primary key as updateable column in af:table, if you have to use then remove primary key from Entity Object
  • Try to validate in RowImpl instead of Expression of Table
  • Surrogate Primary Key
  • Avoid LOV (List of Values) on primary key
  • Change Event Policy of af:table and iterator to none
    these solutions are not rules or conventions, you can only try , and may one of it will work for you

Thursday 27 June 2013

Using af:poll to refresh and push data in page and databound table in ADF

Poll component delivers poll event to server at fixed intervals, we use poll in adf as an alternative of ADS (Active Data Service), this is very simple example of pushing data to page at some fix interval.
Basically af:poll component push data to UI from server.

  • This example contains a page with an af:table binded to Department VO, and I have used a poll component to refresh table periodically.

  • and defined pollListener on af:poll component that sends request to server in every 4 sec, and table get refreshed







  • Other approach to actively push data is ADS, but af:poll is still in use , to refresh table i have written in poll listener

  •         AppModuleAMImpl am = (AppModuleAMImpl)resolvElDC("AppModuleAMDataControl");
    
            ViewObject vo = am.getDepartment1();
            vo.executeQuery();
            i = i + 1;
            this.refreshInfo = "Data Reloaded-" + i+"  Total Row-->"+vo.getRowCount();
            AdfFacesContext.getCurrentInstance().addPartialTarget(refrshMsgBind);
    

  • See the jspx page source code-

  • <?xml version='1.0' encoding='UTF-8'?>
    <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
              xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
        <jsp:directive.page contentType="text/html;charset=UTF-8"/>
        <f:view>
            <af:document title="activePushing.jspx" id="d1">
                <af:messages id="m1"/>
                <af:form id="f1">
                    <af:panelBox id="pb1" showDisclosure="false" text="Active Data Pushing">
                        <f:facet name="toolbar">
                            <af:activeOutputText value="#{ActiveDataPushing.refreshInfo}" id="aot1"
                                                 inlineStyle="font-weight:bold;color:red;"
                                                 binding="#{ActiveDataPushing.refrshMsgBind}"/>
                        </f:facet>
                        <af:table value="#{bindings.Department1.collectionModel}" var="row"
                                  rows="#{bindings.Department1.rangeSize}"
                                  emptyText="#{bindings.Department1.viewable ? 'No data to display.' : 'Access Denied.'}"
                                  fetchSize="#{bindings.Department1.rangeSize}" rowBandingInterval="1"
                                  selectedRowKeys="#{bindings.Department1.collectionModel.selectedRow}"
                                  selectionListener="#{bindings.Department1.collectionModel.makeCurrent}"
                                  rowSelection="single" id="t1" styleClass="AFStretchWidth" contentDelivery="immediate">
                            <af:column sortProperty="#{bindings.Department1.hints.DepartmentId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.DepartmentId.label}" id="c1" width="103">
                                <af:inputText value="#{row.bindings.DepartmentId.inputValue}"
                                              label="#{bindings.Department1.hints.DepartmentId.label}"
                                              required="#{bindings.Department1.hints.DepartmentId.mandatory}"
                                              columns="#{bindings.Department1.hints.DepartmentId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.DepartmentId.precision}"
                                              shortDesc="#{bindings.Department1.hints.DepartmentId.tooltip}" id="it1"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.DepartmentId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.DepartmentId.format}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.DepartmentName.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.DepartmentName.label}" id="c2" width="107">
                                <af:inputText value="#{row.bindings.DepartmentName.inputValue}"
                                              label="#{bindings.Department1.hints.DepartmentName.label}"
                                              required="#{bindings.Department1.hints.DepartmentName.mandatory}"
                                              columns="#{bindings.Department1.hints.DepartmentName.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.DepartmentName.precision}"
                                              shortDesc="#{bindings.Department1.hints.DepartmentName.tooltip}" id="it2"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.DepartmentName.validator}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.ManagerId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.ManagerId.label}" id="c3" width="105">
                                <af:inputText value="#{row.bindings.ManagerId.inputValue}"
                                              label="#{bindings.Department1.hints.ManagerId.label}"
                                              required="#{bindings.Department1.hints.ManagerId.mandatory}"
                                              columns="#{bindings.Department1.hints.ManagerId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.ManagerId.precision}"
                                              shortDesc="#{bindings.Department1.hints.ManagerId.tooltip}" id="it3"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.ManagerId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.ManagerId.format}"/>
                                </af:inputText>
                            </af:column>
                            <af:column sortProperty="#{bindings.Department1.hints.LocationId.name}" sortable="true"
                                       headerText="#{bindings.Department1.hints.LocationId.label}" id="c4" width="105">
                                <af:inputText value="#{row.bindings.LocationId.inputValue}"
                                              label="#{bindings.Department1.hints.LocationId.label}"
                                              required="#{bindings.Department1.hints.LocationId.mandatory}"
                                              columns="#{bindings.Department1.hints.LocationId.displayWidth}"
                                              maximumLength="#{bindings.Department1.hints.LocationId.precision}"
                                              shortDesc="#{bindings.Department1.hints.LocationId.tooltip}" id="it4"
                                              readOnly="true">
                                    <f:validator binding="#{row.bindings.LocationId.validator}"/>
                                    <af:convertNumber groupingUsed="false"
                                                      pattern="#{bindings.Department1.hints.LocationId.format}"/>
                                </af:inputText>
                            </af:column>
                        </af:table>
                        <af:poll id="p1" pollListener="#{ActiveDataPushing.pollListenerActive}" interval="4000"
                                 timeout="5000"/>
                    </af:panelBox>
                </af:form>
            </af:document>
        </f:view>
    </jsp:root>
    

  • Run your application, and do changes from Database and see updated UI at every 4 sec. :-)
 Reloading- 26th times-
 Reloading- 33th times-
 Reloading- 40th times-