Row has been modified by another user and couldn't be updated

I’ve tried every way I can think of to do this and no matter which method I pick, I’m getting the row has been modified by another user error.

When the job is firmed, we need to replace one placeholder material on the job with a different part number, so I’m calling the ChangeJobMtlPartNum method.

I’ve tried it as a method directive (pre and post). I’ve tried it as an in-transaction data directive. And I’ve tried it as an in-transaction data directive that calls an epicor function, but I get the same error no matter what. Any idea how to get this update to go through without the error?
Business Layer Exception

Row has been modified by another user and couldn’t be updated.

Exception caught in: Epicor.ServiceModel

Error Detail

Correlation ID: d79ade4f-e0de-4cc7-a931-a3bce8af1f68
Description: Row has been modified by another user and couldn’t be updated.
Program: Epicor.Ice.dll
Method: Validate
Line Number: 106
Column Number: 21
Table: JobMtl
Field: SysRevID

Client Stack Trace

at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
at Erp.Proxy.BO.JobEntryImpl.Update(JobEntryDataSet ds)
at Erp.Adapters.JobEntryAdapter.OnUpdate()
at Ice.Lib.Framework.EpiBaseAdapter.Update()
at Erp.UI.App.JobEntry.Transaction.Update()

If you’re in post processing, most times you will need do a get by ID in the post and attach the refreshed dataset to the holder.

If its an Input-Output BPM use
this.dsHolder.Attach()

If its a Get By ID (Output Only) use
this.resultsHolder.Attach()

Does this advice apply to a data directive? Where would I add that ? This didn’t work (didn’t expect it to though):

It would not you would have to give the dsholder an actual dataset to attach. Would need to use call context or something to let the post processing, causing this data directive to fire to do a get by ID and pull the new data in. The SysRevID drives this functionality. You need a dataset with that new sysrev.

Do you know if there is an example of this somewhere I could follow?
Or a better way to accomplish this?

Best bet is in post processing somewhere. Here is an example of mangling order release firms.

// Get the BO and Transaction scope
Erp.Contracts.SalesOrderSvcContract orderSvc = Ice.Assemblies.ServiceRenderer.GetService<erp.contracts.salesordersvccontract>(Db);
using (var txscope = IceDataContext.CreateDefaultTransactionScope()) {
     
    // Loop through the BPM dataset.
    foreach (var OH in ds.OrderHed) {
     
        // Look up the DB dataset and make some changes.
        SalesOrderTableset OrderDs = orderSvc.GetByID(OH.OrderNum);
        foreach (OrderRelRow orderRel in OrderDs.OrderRel)
            orderRel.FirmRelease = true;
         
        // Replace the original dataset with the dataset you got from the DB.
        this.dsHolder.Attach(OrderDs);
        // Complete the transaction so Epicor updates the screen.
        txscope.Complete();
    }
}
2 Likes

Also looks like there are quite a few references to it in the forum.

1 Like

I went away from the idea of doing it in a post processing directive because there are too many different ways to firm a job - doing it in a data directive lets me capture all of them with a single procedure. Any ideas for getting around this issue in a data directive?

1 Like

You really can’t from a DD because that is table level stuff happening aside of the dataset temporary tables.

1 Like

thanks for the advice