Sunday, October 24, 2010

ADF Model: Creating Duplicate Row

One of the common requirements in many applications is to duplicate a record of an existing record. Here, I'm going to give you an efficient approach to duplicate a record. Here is the sample application that demonstrates how to create a duplicate row.

Sample UseCase:
Let's take a simple example to create a duplicate record of an existing employee record.  First, the user searches for the employee and selects the employee record from the search results and clicks on button 'Duplicate Record' to duplicate the selected record. And, then the search results table will be refreshed with the newly created (in other words duplicated) row (could be identified by '_DUP' suffix). You can select the record and click on 'View Record' to see the data of the record.


Implementation:
Below is the simple method that duplicates the current emp row.
public void duplicateEmpRecord() { ViewObjectImpl empVO = this.getEmpDeptVO(); Row empCurrentRow = empVO.getCurrentRow(); String[] empAttrs = empCurrentRow.getAttributeNames(); //Skip copying the primay key attributes or any attributes which you want to skip String[] skipAttrs = new String[] { "Empno", "Ename" }; List skipAttrList = Arrays.asList(skipAttrs); //creating a new duplicate row Row dupRow = empVO.createRow(); //copying all attributes one by one for (int i = 0; i < empAttrs.length; i++) { String empAttrName = empAttrs[i]; //For demo purpose, just adding '-DUP' suffix for the original Emp Name. if ("Ename".equals(empAttrName)) dupRow.setAttribute(empAttrName, empCurrentRow.getAttribute(empAttrName) + "_DUP"); int attrIndex = dupRow.getAttributeIndexOf(empAttrName); //Checking if the attribute is in the skip attribute list and the attribute is updatable if (!skipAttrList.contains(empAttrName) && dupRow.isAttributeUpdateable(attrIndex)) //Setting the value for the attributes dupRow.setAttribute(empAttrName, empCurrentRow.getAttribute(empAttrName)); } //Inserting the duplicate row empVO.insertRow(dupRow); }


Explanation: In the above code, we're getting the Emp current row and getting attribute names for the row and iterating through these attributes, to set the attribute values to the newly created row(duplicate row). This will avoid manually specifying each and every attribute name to copy manually. And one thing to note here is that all attributes in the VO may not be updatable. So, we're checking whether a particular attribute in the VO is updatable and setting the value for it only if it's updatable. And, we want to avoid setting values for primary key attributes and unique attributes because setting the same value for these attributes will through 'too many objects match the priamry key...' exception. To avoid that, we're maintaining a list of attributes which we want to skip setting the values. You can see the if condition in the loop. We will be setting values for these attributes manually.

So, this method of copying all attributes to new row is automatic and efficient as we're not manually setting attribute values one by one.

Hope, this would be helpful.

10 comments:

  1. Hi Murali

    Thank you for the example.
    I have to provide the same feature of duplicating row, but in addition to the duplication, I also have to inactivate the current row.
    (Set Active attribute to 'N').

    So I am just setting the current row attribute to N in the same method.

    The duplication and inactivation works fine for 2 times.
    But the 3rd time, the current row attribute is not getting set to N.
    After setting it still shows 'Y'.

    I tried the following
    - set the Active attribute to N 2 times.
    - set the Active Attribute to null before setting to N (after that it never gets reset again)
    - USed Row, ViewRowImpl and Custom XXXRowImpl classes to set the attribute

    But no luck.

    Can you please give me some direction.

    Thanks and Regards
    Sameer

    ReplyDelete
  2. In fact, there is no reason why the Active attribute won't set to 'N'. Just check the following:

    -> Pls make sure you're checking the right row (for the current row)
    -> Are you checking the value change listener, check to see if you're getting the updated values by calling 'processUpdates' method.
    -> Are you checking the value in UI, if so pls check if the corresponding UI component/region is refreshing fine.

    ReplyDelete
  3. Hi Murali

    I made sure that the row I am setting the flag is the current row by debug statements.

    This Active attribute is set to N by the AM method on click of a button. The user does not select the value, so there will be no value change listener.

    I am checking in the UI as well as printing out the attribute value in the AM code for debugging. Both shows the value Y after setting to N.

    Thanks and Regards
    Sameer

    ReplyDelete
  4. Hi Murali

    Just wanted to let you know that the issue here is a unique alternate key which I defined in the EO and I was not using it.
    But somehow it was responsible for this problem.
    It is working as expected now.

    Thanks and Regards
    Sameer

    ReplyDelete
  5. you're a life saver!! thank you!

    ReplyDelete
  6. Hi Team,
    I have used this approach , but its taking more then 2 minutes.

    i have one master table and 5 child tables .
    child table having more then 3000 records.
    its very time consuming . could you please help me to reduce the copy time

    ReplyDelete

Related Posts with Thumbnails