Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label af:table. Show all posts
Showing posts with label af:table. Show all posts

Tuesday 20 May 2014

Blocking row navigation in af:table , synchronize row selection with model in case of validation failure- Oracle ADF

In ADF we often work on editable af:table and when we use af:table to insert ,update or delete data, it is normal to use some validation
but problem is when some validation failure occurs on page (in af:table) ,still we can select another row and it shows as currently selected Row
this is a bit confusing for user as Row Selection of af:table is not synchronized with model or binding layer

See Problem- 
  • I have an editable table on page


  • Added a validation to check negative value in field of LocationId, now navigate to another row


  • See selected focus is on Academic, but problem is when there is validation failure, why it is showing other row as selected ? 



  • If you check in ViewObject , you will find that row with DepartmentName Human Resource is current row

ADF framework provides a property in af:table to control navigation in af:table when there is some error or validation failure- blockRowNavigationOnError
See in oracle docs about this proprty-

Valid Values: always, never, auto


Whether we want to block row navigation in case of validation failure.
This is when you select a row and do some editing inside the table or in a related form, and this editing causes some validation failures. At this time, if you click on a different row in table, we want to block you from moving to the new row.
possible values are: always, never and auto. default value is auto.

  • always means we block the row navigation
  • never means we don't block and let the row navigation happen
  • auto means the framework will make the decision



by default in af:tabel it's value is <auto>


Change it to <always> and now see behavior on page


 now if you try to select another row, it is not get selected and selected focus is on row with validation

Sample ADF Application-Download
Cheers - Happy Learning :-)

Thursday 24 April 2014

Clear af:table filter programmaticallty , reset table filter in 12C (ADF)

Code to reset or clear af:table filter- here searchTabBind is the binding of af:table




    /**
     * method to reset filter attributes on an af:table
     * @param actionEvent event which triggers the method
     */
    public void resetTableFilterAction(ActionEvent actionEvent) {
        FilterableQueryDescriptor queryDescriptor = (FilterableQueryDescriptor) getSearchTabBind().getFilterModel();
        if (queryDescriptor != null && queryDescriptor.getFilterConjunctionCriterion() != null) {
            ConjunctionCriterion cc = queryDescriptor.getFilterConjunctionCriterion();
            List<Criterion> lc = cc.getCriterionList();
            for (Criterion c : lc) {
                if (c instanceof AttributeCriterion) {
                    AttributeCriterion ac = (AttributeCriterion) c;
                    ac.setValue(null);
                }
            }
            getSearchTabBind().queueEvent(new QueryEvent(getSearchTabBind(), queryDescriptor));
        }
    }

use this method on any button or link to clear af:table filter

Thursday 10 April 2014

Pagination in ADF table with Jdeveloper 12.1.2 (ADF 12C) - returned back

Hello All,
Pagination in ADF table was very requested feature after Jdev & ADF 10g.
now in 12C again it is here and quite simple

  • Created a fusion web application using Departments table of HR Schema and dropped it on page as ADF table


  • Now suppose i want to show pagination after 5 rows so to achieve this follow these steps
  • Select table in structure window and go to property inspector change it's scrollPolicy to page ,scrollPolicy is mechanism to scroll data inside table




  • Now select table on page and go to binding tab and select IteratorBinding of Departments table and change rangeSize to 5, by default it is 25 (means fetched 25 rows at a time)


  • Set autoheightRows to 0 and styleClass to AFStretchWidth and you are done now run your page


  • It works good in mozilla ,chrome and IE, but sometimes you can face a problem of finding current row as it may be in second page :-(

Tuesday 4 March 2014

Showing white-spaces properly in ADF table column- 11g & 12c

Hello All,
This posts talks about a requirement of showing white-spaces before any text/number in an af:table
Suppose i have , form and table of a ViewObject on page

Case 1- both table and form are editable , in this case you can see that white spaces are properly visible in both form and table

but normally in applications we have a read-only table and editable form so in this case you can see that white-spaces are not visible in table

But sometimes we need to show spaces in table same as in form so to do this select that field and go to property inspector and select component




Now set it's contentStyle (for input component as- af:inputText) or inlineStyle (for display component as- af:outputText)- white-space:pre;




now run your page and see-

 Cheers :-)


Friday 3 January 2014

Identifying Modified/newely added row in af:table, get all modified rows of viewobject in bean

Hello All,
first of all, a very Happy new year to everyone, learn more and more ADF


this tutorial is about a requirement of showing modified rows on page
Suppose if there is lot of data in af:table and user is modifying some rows then it must reflected immediately on page that which rows are modified for more clarity

Andrejus has also posted about it in 2010
http://andrejusb.blogspot.in/2010/04/changed-row-highlighting-in-oracle-adf.html

But this post talks about two requirements-
  1. Want to highlight modified rows only on page
  2. Want to get modified rows in managed bean
First One could be achieved without writing a single line of code only using expression, a row in table or view object has four state-



  • New
  • Modified
  • Un-Modified
  • Initialized


/* this expression returns state of current row in collection such as table or treeTable*/
#{row.row.entities[0].entityState} 

/*here row is reference variable of collection, this expression returns an int value if it is 
 2-Modified
 0-New
 1-Unmodified
-1-Initialized
*/

  • I'm using Departments table of HR Schema to implement this sample app
  • after business components configuration ,Drop departments VO from data control on page as af:table
  • Now to check row status , i have written following expression in inline style of af:column of af:table, so that it can check state of all rows of table 

  • #{row.row.entities[0].entityState==2 ? 'background-color:orange' : row.row.entities[0].entityState==0 ? 'background-color:darkgreen' : ''} 
    

  • Now Run your page and change any value of table
       After Updating Values in Row- see modified rows are highlighted
  •  Now you are done with first requirement , if we talk about second one, in case you want to get all modified rows in managed bean to perform some operation
  • To achieve this i have used a transient attribute in Departments view Object to store state of each row
  • Now in RowImpl of departments viewobject i have to write some code to get current state of Row, see the getter method of transient attribute in RowImpl

  •     /**
         * Gets the attribute value for the calculated attribute CheckRowStatus.
         * @return the CheckRowStatus
         */
        public Integer getCheckRowStatus() {
            byte entityState = this.getEntity(0).getEntityState();
            return new Integer(entityState);
    
            // return (Integer) getAttributeInternal(CHECKROWSTATUS);
        }
    

  • Now i have placed a button on page to get all modified rows and show a message on page through managed bean
  • See the method written in ApplicationModuleImpl class and then exposed to client to be used in managed bean action event

  •     /**Method to get all modified rows and store corresponding Department Name in an ArrayList
         * @return
         */
        public ArrayList<String> getModifiedRows() {
            ArrayList<String> deptNm = new ArrayList<String>();
            ViewObject deptVo = this.getDepartmentsView1();
            RowSetIterator deptIter = deptVo.createRowSetIterator(null);
            while (deptIter.hasNext()) {
                Row nextRow = deptIter.next();
                if (nextRow.getAttribute("CheckRowStatus") != null) {
                    Integer rowStatus = (Integer)nextRow.getAttribute("CheckRowStatus");
                    if (rowStatus == 2) {
                        deptNm.add(nextRow.getAttribute("DepartmentName").toString());
                    }
                }
            }
            return deptNm;
    
        }
    

  • Now call this method in managed bean through Binding Layer

  •     /**Method to get BindingContainer of current page
         * @return
         */
        public BindingContainer getBindings() {
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**Method to call AM method and to show modified rows on page in FacesMessage
         * @param actionEvent
         */
        public void getModifiedRows(ActionEvent actionEvent) {
            OperationBinding ob = getBindings().getOperationBinding("getModifiedRows");
            ob.execute();
            if (ob.getResult() != null) {
                ArrayList<String> deptName = (ArrayList<String>)ob.getResult();
                StringBuilder saveMsg =
                    new StringBuilder("<html><body><b><p style='color:red'>Modified Rows in Departments table are-</p></b>");
    
                saveMsg.append("<ul>");
                for (String name : deptName) {
                    System.out.println(name);
                    saveMsg.append("<li> <b>" + name + "</b></li>");
                }
    
                saveMsg.append("</ul><br>");
                saveMsg.append("</body></html>");
                FacesMessage msg = new FacesMessage(saveMsg.toString());
                FacesContext.getCurrentInstance().addMessage(null, msg);
            }
        }
    

  • Now again run this page and change some departments then click on get modified rows, it will show currently modified rows

Cheers- Download Sample App

Tuesday 26 November 2013

Apply Filter on af:table column programmatically ,Invoke 'FilterableQueryDescriptor' through managed bean

Hello All
This tutorial is about a requirement of filtering af:table column through code,
to achieve this we can invoke FilterableQueryDescriptor (FilterableQueryDescriptor is an abstract subclass of QueryDescriptor. It adds support for filtering of data and is typically used by the table component to filter data from a query )

Suppose i have department table and i have to filter on department column-
  • Create a Fusion Web Application and business components for Departments (HR Schema) table
  • now drag table on page and bind it to bean
  • Now drop a input text and button on page to enter Department Name
  • bind input text to bean and create ActionListener on button to filter Department Table
See XML source of Page-




<?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="filterPage.jspx" id="d1">
            <af:messages id="m1"/>
            <af:form id="f1">
                <af:inputText label="Department Name" id="it5"
                              binding="#{pageFlowScope.FilterProgrammaticBean.deptNmBind}"/>
                <af:commandButton text="Filter" id="cb1"
                                  actionListener="#{pageFlowScope.FilterProgrammaticBean.filterTableAction}"/>
                <af:table value="#{bindings.DepartmentsView1.collectionModel}" var="row"
                          rows="#{bindings.DepartmentsView1.rangeSize}"
                          emptyText="#{bindings.DepartmentsView1.viewable ? 'No data to display.' : 'Access Denied.'}"
                          fetchSize="#{bindings.DepartmentsView1.rangeSize}" rowBandingInterval="1"
                          selectedRowKeys="#{bindings.DepartmentsView1.collectionModel.selectedRow}"
                          selectionListener="#{bindings.DepartmentsView1.collectionModel.makeCurrent}"
                          rowSelection="single" id="t1" styleClass="AFStretchWidth"
                          binding="#{pageFlowScope.FilterProgrammaticBean.deptTabBind}"
                          filterModel="#{bindings.DepartmentsView1Query.queryDescriptor}"
                          queryListener="#{bindings.DepartmentsView1Query.processQuery}" filterVisible="true"
                          varStatus="vs">
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.DepartmentId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.DepartmentId.label}" id="c1"
                               filterable="true">
                        <af:inputText value="#{row.bindings.DepartmentId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.DepartmentId.label}"
                                      required="#{bindings.DepartmentsView1.hints.DepartmentId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.DepartmentId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.DepartmentId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.DepartmentId.tooltip}" id="it1"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.DepartmentId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.DepartmentId.format}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.DepartmentName.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.DepartmentName.label}" id="c2"
                               filterable="true">
                        <af:inputText value="#{row.bindings.DepartmentName.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.DepartmentName.label}"
                                      required="#{bindings.DepartmentsView1.hints.DepartmentName.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.DepartmentName.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.DepartmentName.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.DepartmentName.tooltip}" id="it2"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.DepartmentName.validator}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.ManagerId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.ManagerId.label}" id="c3"
                               filterable="true">
                        <af:inputText value="#{row.bindings.ManagerId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.ManagerId.label}"
                                      required="#{bindings.DepartmentsView1.hints.ManagerId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.ManagerId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.ManagerId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.ManagerId.tooltip}" id="it3"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.ManagerId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.ManagerId.format}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.LocationId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.LocationId.label}" id="c4"
                               filterable="true">
                        <af:inputText value="#{row.bindings.LocationId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.LocationId.label}"
                                      required="#{bindings.DepartmentsView1.hints.LocationId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.LocationId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.LocationId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.LocationId.tooltip}" id="it4"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.LocationId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.LocationId.format}"/>
                        </af:inputText>
                    </af:column>
                </af:table>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Managed Bean Code-


package filter.view;

import java.util.Map;

import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.event.QueryEvent;
import oracle.adf.view.rich.model.FilterableQueryDescriptor;


public class FilterProgrammaticBean {
    private RichInputText deptNmBind;
    private RichTable deptTabBind;

    public FilterProgrammaticBean() {
    }

    public void setDeptNmBind(RichInputText deptNmBind) {
        this.deptNmBind = deptNmBind;
    }

    public RichInputText getDeptNmBind() {
        return deptNmBind;
    }

    public void setDeptTabBind(RichTable deptTabBind) {
        this.deptTabBind = deptTabBind;
    }

    public RichTable getDeptTabBind() {
        return deptTabBind;
    }

    /**Method to invoke FilterableQueryDescriptor and Filter Department table
     * @param actionEvent
     */
    public void filterTableAction(ActionEvent actionEvent) {
        RichTable tbl = this.getDeptTabBind();
        FilterableQueryDescriptor filterQD = (FilterableQueryDescriptor)tbl.getFilterModel();
        Map filterCriteria = filterQD.getFilterCriteria();
        filterCriteria.put("DepartmentName", deptNmBind.getValue());
        getDeptTabBind().queueEvent(new QueryEvent(getDeptTabBind(), filterQD));
        AdfFacesContext.getCurrentInstance().addPartialTarget(this.getDeptTabBind());
    }
}

Run your Application-





Cheers- Download Sample App

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 :-)

Wednesday 14 August 2013

Importance of BC4J temp tables(PS_TXN & PS_TXN_SEQ) and Persistent Collections Facility in Oracle ADF





Recently i have seen a new exception in my production environment while 7 users working on deployed application








[2013-08-12T14:06:58.191+05:30] [AdminServer] [WARNING] [ADF_FACES-00009] [oracle.adf.view.rich.component.fragment.UIXRegion] [tid: [ACTIVE].ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: 11] [ecid: a8c0f3836ec62479:-26ea53cb:1407155e369:-8000-00000000000006e7,0] [APP: EBIZADF.ear] Error processing viewId: /ApplicationRoleTF/AppRole URI: /AppRole.jsff actual-URI: /AppRole.jsff.[[
oracle.jbo.PCollException: JBO-28030: Could not insert row into table PS_TXN, collection id 420,356, persistent id 1
 at oracle.jbo.PCollException.throwException(PCollException.java:36)
 at oracle.jbo.pcoll.OraclePersistManager.insert(OraclePersistManager.java:1905)
 at oracle.jbo.pcoll.PCollNode.passivateElem(PCollNode.java:564)
 at oracle.jbo.pcoll.PCollNode.passivate(PCollNode.java:688)
 at oracle.jbo.pcoll.PCollNode.passivateBranch(PCollNode.java:647)
 at oracle.jbo.pcoll.PCollection.passivate(PCollection.java:464)
 at oracle.jbo.server.DBSerializer.passivateRootAM(DBSerializer.java:294)
 at oracle.jbo.server.DBSerializer.passivateRootAM(DBSerializer.java:267)
 at oracle.jbo.server.ApplicationModuleImpl.passivateStateInternal(ApplicationModuleImpl.java:6046)
 at oracle.jbo.server.ApplicationModuleImpl.passivateState(ApplicationModuleImpl.java:5906)
 at oracle.jbo.common.ampool.DefaultConnectionStrategy.reconnect(DefaultConnectionStrategy.java:290)
 at oracle.jbo.server.ApplicationPoolMessageHandler.doPoolReconnect(ApplicationPoolMessageHandler.java:609)
 at oracle.jbo.server.ApplicationPoolMessageHandler.doPoolMessage(ApplicationPoolMessageHandler.java:399)
 at oracle.jbo.server.ApplicationModuleImpl.doPoolMessage(ApplicationModuleImpl.java:9053)
 at oracle.jbo.common.ampool.ApplicationPoolImpl.sendPoolMessage(ApplicationPoolImpl.java:4606)
 at oracle.jbo.common.ampool.ApplicationPoolImpl.prepareApplicationModule(ApplicationPoolImpl.java:2536)
 at oracle.jbo.common.ampool.ApplicationPoolImpl.doCheckout(ApplicationPoolImpl.java:2346)
 at oracle.jbo.common.ampool.ApplicationPoolImpl.useApplicationModule(ApplicationPoolImpl.java:3245)
 at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:571)
 at oracle.jbo.http.HttpSessionCookieImpl.useApplicationModule(HttpSessionCookieImpl.java:234)
 at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:504)
 at oracle.jbo.common.ampool.SessionCookieImpl.useApplicationModule(SessionCookieImpl.java:499)
 at oracle.adf.model.bc4j.DCJboDataControl.initializeApplicationModule(DCJboDataControl.java:517)
 at oracle.adf.model.bc4j.DCJboDataControl.getApplicationModule(DCJboDataControl.java:867)
 at oracle.adf.model.binding.DCBindingContainer.findDataControl(DCBindingContainer.java:1659)
 at oracle.adf.model.binding.DCIteratorBinding.initDataControl(DCIteratorBinding.java:2542)
 at oracle.adf.model.binding.DCIteratorBinding.getDataControl(DCIteratorBinding.java:2477)
 at oracle.adf.model.binding.DCIteratorBinding.getCheckedDataControl(DCIteratorBinding.java:2571)
 at oracle.adf.model.binding.DCIteratorBinding.executeQueryIfNeeded(DCIteratorBinding.java:2219)
 at oracle.adf.model.binding.DCBindingContainer.internalRefreshControl(DCBindingContainer.java:3279)
 at oracle.adf.model.binding.DCBindingContainer.refresh(DCBindingContainer.java:2906)
 at oracle.adf.controller.internal.binding.TaskFlowRegionController.doRegionRefresh(TaskFlowRegionController.java:284)
 at oracle.adf.controller.internal.binding.TaskFlowRegionController.refreshRegion(TaskFlowRegionController.java:134)
 at oracle.adf.model.binding.DCBindingContainer.internalRefreshControl(DCBindingContainer.java:3237)
 at oracle.adf.model.binding.DCBindingContainer.refresh(DCBindingContainer.java:2906)
 at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.prepareModel(PageLifecycleImpl.java:115)
 at oracle.adf.controller.faces.lifecycle.FacesPageLifecycle.prepareModel(FacesPageLifecycle.java:392)
 at oracle.adf.controller.v2.lifecycle.Lifecycle$2.execute(Lifecycle.java:149)
 at oracle.adfinternal.controller.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:197)
 at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener.access$400(ADFPhaseListener.java:23)
 at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener$PhaseInvokerImpl.startPageLifecycle(ADFPhaseListener.java:238)
 at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener$1.after(ADFPhaseListener.java:274)
 at oracle.adfinternal.controller.faces.lifecycle.ADFPhaseListener.afterPhase(ADFPhaseListener.java:75)
 at oracle.adfinternal.controller.faces.lifecycle.ADFLifecyclePhaseListener.afterPhase(ADFLifecyclePhaseListener.java:53)
 at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:447)
 at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:202)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
 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:301)
 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:125)
 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:119)
 at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
 at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:442)
 at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:103)
 at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:171)
 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:139)
 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:3730)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
 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:2273)
 at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
 at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:221) 
 
 
And i was not able understand why this exception occurs, i googled about it and found some very interesting facts about BC4J.

BC4J creates temporary database object (PS_TXN and PS_TXN_SEQ), that are used by ADF to maintain state of user session as per DB, it has facility to store temporary data in BLOB column to avoid out of memory problem.
visit this link to read about these objects- (How to manage PS_TXN and PS_TXN_SEQ)
http://www.oracle.com/technetwork/developer-tools/jdev/overview/bc4j-temp-tables-087270.html#ID34

now i have seen cascading exception after this  oracle.jbo.PcollException, PColl refers persistent collection facility.
when ADF was unable to insert data in PS_TXN table, java.sql.SQLException occurs, connection forcefully closed


Caused by: oracle.jbo.JboException: JBO-29000: Unexpected exception caught: java.sql.SQLException, msg=Connection has already been closed.
 at oracle.jbo.server.DBTransactionImpl.getDatabaseProductName(DBTransactionImpl.java:1248)
 at oracle.jbo.server.DBTransactionImpl.getInternalConnection(DBTransactionImpl.java:1355)
 at oracle.jbo.server.DBTransactionImpl.getPersistManagerConnection(DBTransactionImpl.java:1282)
 at oracle.jbo.pcoll.PCollManager.ensureConnection(PCollManager.java:486)
 at oracle.jbo.pcoll.OraclePersistManager.getConnection(OraclePersistManager.java:153)
 at oracle.jbo.pcoll.OraclePersistManager.insert(OraclePersistManager.java:1885)
 at oracle.jbo.pcoll.PCollNode.passivateElem(PCollNode.java:564)
 at oracle.jbo.pcoll.PCollNode.passivate(PCollNode.java:688)
 at oracle.jbo.pcoll.PCollNode.passivateBranch(PCollNode.java:647)
 at oracle.jbo.pcoll.PCollection.passivate(PCollection.java:464)
 at oracle.jbo.server.DBSerializer.passivateRootAM(DBSerializer.java:294)
 at oracle.jbo.server.DBSerializer.passivateRootAM(DBSerializer.java:267)
 at oracle.jbo.server.ApplicationModuleImpl.passivateStateInternal(ApplicationModuleImpl.java:6046)
 at oracle.jbo.server.ApplicationModuleImpl.passivateState(ApplicationModuleImpl.java:5906)


  • Now i have counted rows in PS_TXN , there was more 3000 rows, have cleared all rows



  • after this again 7 users worked for 3hrs and there was no exception, no bizarre behaviour
  • Now once connection is closed, ADF errors starts coming out as NullPointerException

  • javax.faces.el.EvaluationException: java.lang.NullPointerException
     at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:51)
     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
     at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
     at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:783)
     at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1248)
    

  • Finally what i come to know that in order to avoid this kind of exceptions , we have to schedule a job to clear data in PS_TXN

What PS_TXN stores-

  • PS_TXN structure- 
     
  • Suppose you have a search query with more that 10000 records and that is on page as af:table, when user scrolls through table to view records then to avoid out of memory problem bc4j stores extra result set in a temporary storage (PS_TXN) in BLOB column
  • When AM (Application Module) passivates and in AM pooling dofailover is set to true,pending state and changes are stored in this table

  • <AM-Pooling jbo.dofailover="true"/> 
     

  • In case of Multiple users , session information stored in PS_TXN, each user session must be serialised with database, otherwise database object can't behave as per separate user session
  • to test a scenario , i have deleted all data from PS_TXN in default HR Schema and created a ADF application  that makes uses of HR's tables

  • Run that application , till few operations on application there was no data in PS_TXN table , when i opened application in 3 browser's window and then performed some operations after this there was 2 rows in PS_TXN, it means ADF automatically insert data in PS_TXN for state,session,AM Changes. developer need not to worry about it

At-last summary is - Always keep in mind these db objects if you are facing unexpected behaviour of ADF application in production (multi user) environment, if your application working perfectly on development environment but not in production always check it and schedule a job to clear table PS_TXN