Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label Business Component. Show all posts
Showing posts with label Business Component. Show all posts

Thursday 12 January 2017

ADF Basics: Duplicate Record Validation Using Model Level Business Rules


Hello All

Hope you all are doing well :)

When we are creating any data entry form , at that time preventing duplicate entries for some of attributes is very basic validation requirement .

Suppose We are creating a form to make new Departments entry and  there should not be two departments with same name so for this type of validation we need not to write single line of code in Oracle ADF as there are predefined business rules for basic validation

Friday 16 January 2015

Setting view object bind variable (Override bindParametersForCollection, prepareRowSetForQuery, executeQueryForCollection )

Hello All,
This post is about a very basic question- How to set bind variable of a view object ?
and there are multiple posts about it that describes multiple ways to do this
Using setNamedWhereClause
Using VariableValueManager 
Using setter method in VOImpl class

But Sometimes we can not assign bind variable value in declarative way for first time execution as value source for bind variable is fixed but it's value may change at runtime from n number of events



So for this type of requirement we can set bind variable's value in such a way so that we need not to write code everywhere to set changed value.
See how can we do this -

  • Create a Fusion Web Application and prepare model using Departments table of HR Schema




  • Open Departments viewObject add a bind variable in it's query , this bind variable is further used to set value and filter result set





  • Create Java class for Department view object, goto java tab of Departments VO and click on edit icon of Java Classes and select "Generate ViewObject Class"





  • Now we can set bind variable's value by overriding 3 methods of DepartmentVOImpl class

1. Overriding bindParametersForCollection in ViewObject java class -

This method is used to set bind variable's value by framework, framework supplies an array of all bind variable to this method We can override this method to set value of bind variable ,
Open DepartmentVOImpl class and click on override methods icon on top of editor
It will open a window that consist all methods , search by name and click on ok



See the code in DepartmentVOImpl-


    /**@override Method to set bind variable's value at runtime (Framework Internal Method)
     * @param queryCollection
     * @param object
     * @param preparedStatement
     * @throws SQLException
     */
    protected void bindParametersForCollection(QueryCollection queryCollection, Object[] object,
                                               PreparedStatement preparedStatement) throws SQLException {
        for (Object bindVar : object) {
            // Iterate over bind variable set and find specific bind variable
            if (((Object[])bindVar)[0].toString().equals("BindDeptId")) {
                // set the bind variable's  value
                ((Object[])bindVar)[1] = 100;

            }
        }
        super.bindParametersForCollection(queryCollection, object, preparedStatement);

    }

2. Overriding prepareRowSetForQuery in ViewObject java class -

This method (introduce in 11.1.1.5 release) executes before bindParametersForCollection , same thing can also be done in this method 
Override method in Impl class 


See the Code in DepartmentsVOImpl-


    /**@override Method to prepare RowSet for execution(Framework Internal Method)
     * @param viewRowSetImpl
     */
     public void prepareRowSetForQuery(ViewRowSetImpl viewRowSetImpl) {
        //Set Bind Variable's value 
        viewRowSetImpl.ensureVariableManager().setVariableValue("BindDeptId", 100);
        super.prepareRowSetForQuery(viewRowSetImpl);
    } 

3. Overriding executeQueryForCollection in ViewObject java class -


This method invokes just before framework executes rowset , avoid setting bind varibale in this method because it is not called before some methods as getEstimatedRowCount(), So whenever you try to get rowcount it will return wrong values 
still it works and sets the bind varible value and executes rowset, again override method



See the Code in DepartmentsVOImpl-


    /**Method to excute viewObject rowSet(Framework Internal Method)
     * @param object
     * @param object2
     * @param i
     */
    protected void executeQueryForCollection(Object object, Object[] object2, int i) {
        for (Object bindVar : object2) {
            // Iterate over bind variable set and find specific bind variable
            if (((Object[])bindVar)[0].toString().equals("BindDeptId")) {
                // Set the bind variable value
                ((Object[])bindVar)[1] = 100;

            }
        }
        super.executeQueryForCollection(object, object2, i);
    }

Now use anyone of these methods to set bind variable value and run application module, check result
It is showing data for DepartmentId 100.

Thanks, Happy Learning :)

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

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




Thursday 18 July 2013

JBO-27022-Failed to load value at index 'n' , java.sql.SQLException: Invalid column index in Oracle ADF

'Invalid column index' is the error occurs due to SQL Exception in ADF Faces.
and main reason behind this is mismatch between ViewObject's query and Attributes.
 suppose i have an application with default HR Schema and Employees Table.

  • See the query and attribute list of Employees ViewObject , when there is no mismatch between attributes and query
and query is -


  • Now i have removed a attribute from ViewObject query, then mismatch between VO Query and attribute list tends towards sql exception "Invalid Column Index"



 Query is- (First_Name is not there)

  •  Now when you try to run application, this error occurs, "Failed to load value at index n - java.sql.SQLException Invalid column index"- see error log 

  • oracle.jbo.AttributeLoadException: JBO-27022: Failed to load value at index 11 with java object of type java.lang.String due to java.sql.SQLException.
     at oracle.jbo.server.AttributeDefImpl.loadFromResultSet(AttributeDefImpl.java:2435)
     at oracle.jbo.server.ViewRowImpl.populate(ViewRowImpl.java:3842)
     at oracle.jbo.server.ViewDefImpl.createInstanceFromResultSet(ViewDefImpl.java:2387)
     at oracle.jbo.server.ViewObjectImpl.createRowFromResultSet(ViewObjectImpl.java:6030)
     at oracle.jbo.server.ViewObjectImpl.createInstanceFromResultSet(ViewObjectImpl.java:5861)
     at oracle.jbo.server.QueryCollection.populateRow(QueryCollection.java:3612)
     at oracle.jbo.server.QueryCollection.fetch(QueryCollection.java:3467)
     at oracle.jbo.server.QueryCollection.get(QueryCollection.java:2184)
     at oracle.jbo.server.ViewRowSetImpl.getRow(ViewRowSetImpl.java:5125)
     at oracle.jbo.server.ViewRowSetIteratorImpl.doFetch(ViewRowSetIteratorImpl.java:2936)
     at oracle.jbo.server.ViewRowSetIteratorImpl.ensureRefreshed(ViewRowSetIteratorImpl.java:2792)
     at oracle.jbo.server.ViewRowSetIteratorImpl.refresh(ViewRowSetIteratorImpl.java:3033)
     at oracle.jbo.server.ViewRowSetImpl.notifyRefresh(ViewRowSetImpl.java:2797)
     at oracle.jbo.server.ViewRowSetImpl.execute(ViewRowSetImpl.java:1255)
     at oracle.jbo.server.ViewRowSetImpl.executeQueryForMasters(ViewRowSetImpl.java:1413)
     at oracle.jbo.server.ViewRowSetImpl.executeQueryForMode(ViewRowSetImpl.java:1319)
     at oracle.jbo.server.ViewRowSetImpl.executeQuery(ViewRowSetImpl.java:1304)
     at oracle.jbo.server.ViewObjectImpl.executeQuery(ViewObjectImpl.java:7119)
     at oracle.adf.model.bc4j.DCJboDataControl.executeIteratorBindingIfNeeded(DCJboDataControl.java:1366)
     at oracle.adf.model.binding.DCIteratorBinding.executeQueryIfNeeded(DCIteratorBinding.java:2219)
     at oracle.jbo.uicli.binding.JUCtrlHierBinding.getRootNodeBinding(JUCtrlHierBinding.java:92)
     at oracle.adfinternal.view.faces.model.binding.FacesCtrlHierBinding$HierCurrencyRowKeySet.getRowIterator(FacesCtrlHierBinding.java:1421)
     at oracle.adfinternal.view.faces.model.binding.CurrencyRowKeySet.size(CurrencyRowKeySet.java:34)
     at org.apache.myfaces.trinidad.model.RowKeySet.getSize(RowKeySet.java:152)
     at oracle.adfinternal.view.faces.renderkit.rich.TableRendererUtils.writePojoSelectionState(TableRendererUtils.java:455)
     at oracle.adfinternal.view.faces.renderkit.rich.TableRenderer.renderDataBlockRows(TableRenderer.java:2562)
     at oracle.adfinternal.view.faces.renderkit.rich.TableRenderer.encodeAll(TableRenderer.java:685)
     at oracle.adf.view.rich.render.RichRenderer.encodeAll(RichRenderer.java:1452)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeEnd(CoreRenderer.java:511)
     at org.apache.myfaces.trinidad.component.UIXComponentBase.encodeEnd(UIXComponentBase.java:923)
     at org.apache.myfaces.trinidad.component.UIXCollection.encodeEnd(UIXCollection.java:617)
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeChild(CoreRenderer.java:624)
     at oracle.adf.view.rich.render.RichRenderer.encodeChild(RichRenderer.java:3201)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeAllChildren(CoreRenderer.java:641)
     at oracle.adf.view.rich.render.RichRenderer.encodeAllChildrenInContext(RichRenderer.java:3062)
     at oracle.adfinternal.view.faces.renderkit.rich.FormRenderer.encodeAll(FormRenderer.java:274)
     at oracle.adf.view.rich.render.RichRenderer.encodeAll(RichRenderer.java:1452)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeEnd(CoreRenderer.java:511)
     at org.apache.myfaces.trinidad.component.UIXComponentBase.encodeEnd(UIXComponentBase.java:923)
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeChild(CoreRenderer.java:624)
     at oracle.adf.view.rich.render.RichRenderer.encodeChild(RichRenderer.java:3201)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeAllChildren(CoreRenderer.java:641)
     at oracle.adf.view.rich.render.RichRenderer.encodeAllChildrenInContext(RichRenderer.java:3062)
     at oracle.adfinternal.view.faces.renderkit.rich.DocumentRenderer.encodeAll(DocumentRenderer.java:1277)
     at oracle.adf.view.rich.render.RichRenderer.encodeAll(RichRenderer.java:1452)
     at org.apache.myfaces.trinidad.render.CoreRenderer.encodeEnd(CoreRenderer.java:511)
     at org.apache.myfaces.trinidad.component.UIXComponentBase.encodeEnd(UIXComponentBase.java:923)
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
     at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
     at oracle.adfinternal.view.faces.component.AdfViewRoot.encodeAll(AdfViewRoot.java:91)
     at com.sun.faces.application.view.JspViewHandlingStrategy.doRenderView(JspViewHandlingStrategy.java:431)
     at com.sun.faces.application.view.JspViewHandlingStrategy.renderView(JspViewHandlingStrategy.java:233)
     at org.apache.myfaces.trinidadinternal.application.ViewDeclarationLanguageFactoryImpl$ChangeApplyingVDLWrapper.renderView(ViewDeclarationLanguageFactoryImpl.java:350)
     at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
     at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
     at org.apache.myfaces.trinidadinternal.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:165)
     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._renderResponse(LifecycleImpl.java:1027)
     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:334)
     at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:232)
     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
     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.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)
    Caused by: java.sql.SQLException: Invalid column index
     at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:2824)
     at weblogic.jdbc.wrapper.ResultSet_oracle_jdbc_driver_OracleResultSetImpl.getString(Unknown Source)
     at oracle.jbo.common.StringTypeSQLNativeImpl.getDataFromResultSet(JboTypeMapEntries.java:509)
     at oracle.jbo.server.AttributeDefImpl.loadFromResultSet(AttributeDefImpl.java:2426)
     ... 97 more
    ## Detail 0 ## 
     
  • So when you see this type of log , first check your viewObjects and their query.
  • Always match attribute order in query of view object and in XML source, if there is mismatch in order, it may result in  great problem or data mistake
        See here is difference in order of attribute of vo and query- (Last_Name and Email)


  • In this case of mismatch in order, two things may happen-
  • First one- if Data type of mismatched attributes matches (as Last_Name and Email both are Var char) then value in both fields will be set in VO otherwise it will throw an exception.
  • See this scenario in given snap- Only due to wrong ordering ,value of Last_Name and Email got replaced


  • And if you have Impl classes for your Entity Object or View Object then also check indexing in  classes ,query and  XML source.
  • Invalid Column Index may also occur due to pl/sql (database) function call, always check it and its parameter indexing