Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label EOImpl class. Show all posts
Showing posts with label EOImpl class. Show all posts

Monday, 5 January 2015

ADF Basics: Delete child records on delete of parent record, Overriding remove() in EntityObject class

This post is about one basic question of Master-Detail relation between business components
How to delete all child records on delete of parent record ?
So answer is quite simple , see the steps how to achieve this?

  • Create a Fusion Web Application and prepare model project using Departments and Employees table of HRSchema.
    you can see multiple associations and viewLinks are created automatically due to foreign key relation in database


  • Here Departments is parent table and Employees is child, so there is an association between both entity objects , open this association and goto Association Properties . Now you can see source and destination accessor name that are created in both entity objects




  • Next step is to create EntityObject java class. To do this open Departments entity object -- go to java section-- click on edit icon and check the box to create class and required methods
    See Accessors and Remove Method will be created in this class


  • Open DepartmentsEOImpl class and check there is a method that returns RowIterator of Employees (this is Accessor)

  •     /**
         * @return the associated entity oracle.jbo.RowIterator.
         */
        public RowIterator getEmployeesEO1() {
            return (RowIterator)getAttributeInternal(EMPLOYEESEO1);
        }
    

  • Now locate remove method in EOImpl, this method is called every time when delete operation for Departments is executed so add this code to remove(); method

  •     /**
         * Add entity remove logic in this method.
         */
        public void remove() {
            //Get all Employees of currenlty selected Department
            RowIterator employees = getEmployeesEO1();
            while (employees.hasNext()) {
                //Delete all Employees
                employees.next().remove();
            }
            //Delete Department itself after deleting all Employees associated with it
            super.remove();
        }
    


This is how we can make use EntityObject class and Association accessors, in the same way other operation can be performed as updating all child rows, sum of a column of child records etc
Thnaks , Happy Learning :)

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




Tuesday, 25 June 2013

Conditional Execution of Model (EO) level Validation- Oracle ADF

You all know about ADF model level validation , we can apply variety of validation on model (Entity Object), as for length, compare, key, regular expression, script and unique key etc.

I am not going to describe whole process for model layer validation, for detailed tutorial on EO level validation see -Dynamic (parameterize) model level validation using message token
Now see how we can execute these validation conditionally -

  • When we apply unique key validation on Entity Object- this window appears-
  • Now go to Validation Execution and write your condition in given box for that you want to execute validation

  • Now go to Failure Handling tab and write your failure handling message, and you are done




  • Now run your application and see how validation executes for your condition
  • this functionality is really helpful and sometimes avoids writing lot of managed bean code

Friday, 23 November 2012

ADF Basics: Set Default Values in Entity Object for every CreateInsert

Sometimes we have to set some same(default) values for each new row for this we use literal value option in EntityObject XML file or we can set that value in EO(EntityObject) Impl class.
EOImpl Class has a method named

 protected void create(AttributeList attributeList) {
        super.create(attributeList);
}

You can set default values there
For this we have to create Entity Impl class of EntityObject , Open EntityObject and select Java tab and click on edit icon


Check Accessors and Create Method checkbox


Now set values using accessors like this -


    /**
     * Add attribute defaulting logic in this method.
     * @param attributeList list of attribute names/values to initialize the row
     */
    protected void create(AttributeList attributeList) {
        //Setting default values
        setEmail("example@gmail.com");
        setPhoneNumber("99999999");
        super.create(attributeList);
    }


or can set in Literal Value of EO xml file

Set default value in Entity Object Literal Value

This is how you can set default values in Entity Object