Hi all, Jdev Version: Studio Edition Version 18.104.22.168.0 Business Requirement: Need to partially commit the deletion of one row (say Row-A) in EO and serialize another row (an addition say Row-B) for committing after approval.
How we achieve this:
Step 1 - Make the change in Row-A & Row-B on my main AM (AM1).
Step 2 - create a parallel new root AM (AM2) and make the changes that need to be partially committed on the VO/EO in this new root AM (AM2) and issue commit on this AM (AM2).
Step 3 - Now after the partial commit, am back to AM1 where I would like to serialize only the change on Row-B. So I call the remove() on Row-A and passivate.
Step 4- On my offline approval page, I invoke activate to show the new addition Row-B for approval post which I can invoke commit. Issue we face: When we passivate in Step 3, the deletion of Row-A also gets passivated. As a result, this row shows up on my approval screen. On my approval screen, only Row-B should be displayed.
Appreciate your inputs on this issue.
row A will be deleted with the next commit the way you put it. My interpretation is you want to remove it from the collection in which case you would call removeRowFromCollection on the VO. Instead of what you are doing here I would consider a soft-delete in which you set a delete flag on a row instead of deleting or commiting it. You can then use a custom RowMatcher on a VO to filter those entities out in which case you only see those for approval that you need to see.
For partial commits, I would use a different strategy. Create a headless task flow (no view activity just a method activity and a return activity) and have it configured to not share the Data Control (isolated) You then pass in the information for the row to commit, query it in the method activity (through a VO) update the VO and commit the change using the commit method from the DataControl frame (you get this through the BindingContext class.
This is more declarative and reusable than creating an AM just for this purpose. However, keep in mind that the callingg task flow still things Row A is changed (as it doesn't participate in the commit. So what you do is to call row.refresh() and issue DB forget changes as an argument so Row A is reset to the state that is in the database
Thanks for suggesting the alternate approach.
I tried the row.refresh(Row.REFRESH_WITH_DB_FORGET_CHANGES) - this works for addition/updation of rows. But for deleted rows, this throws a row locked for update exception. Any suggestion on how to handle the deleted row?
The exception when I call the refresh() method is RowAlreadyDeletedException and this has already been discussed in another thread - DCBindingIterator refresh only one row .
Is there a way to remove the deleted row from entity so that my current transaction does not this is a entity change any longer?
Finally worked around this with below code -
When an entity changes it adds an entry in the Transaction Post Listener & in Transaction Listener. Removing the entity from these listeners (though not usually recommended) will ensure that these changes are not committed as part of present transaction. The refresh approach seems to work for newly added & updated records - but not for deleted records and I see the same in many forum posts.
So for deletions, the removal from transaction listeners can be the workaround until ADF provides a mechanism to handle the deleted records using refresh() method itself.