Skip to content

Commit

Permalink
DocumentCollection.duplicateDocument shall run in transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
teosarca committed Sep 22, 2017
1 parent 5972a8d commit 58de729
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ public JSONDocument duplicate(

final DocumentPath fromDocumentPath = DocumentPath.rootDocumentPath(WindowId.fromJson(windowIdStr), DocumentId.of(documentIdStr));

// NOTE: deliberately we are not running in a transaction so basically we will ask the duplicate method to copy as much as it can ;)
final Document documentCopy = documentCollection.duplicateDocument(fromDocumentPath);
return JSONDocument.ofDocument(documentCopy, newJSONOptions().setShowAdvancedFields(advanced).build());
}
Expand Down
21 changes: 19 additions & 2 deletions src/main/java/de/metas/ui/web/window/model/DocumentCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
import org.adempiere.ad.expression.api.LogicExpressionResult;
import org.adempiere.ad.persistence.TableModelLoader;
import org.adempiere.ad.trx.api.ITrx;
import org.adempiere.ad.trx.api.ITrxManager;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.model.CopyRecordFactory;
import org.adempiere.model.CopyRecordSupport;
import org.adempiere.model.InterfaceWrapperHelper;
import org.adempiere.model.PlainContextAware;
import org.adempiere.model.RecordZoomWindowFinder;
import org.adempiere.util.Check;
import org.adempiere.util.Services;
import org.adempiere.util.lang.IAutoCloseable;
import org.adempiere.util.lang.impl.TableRecordReference;
import org.compiere.model.PO;
Expand Down Expand Up @@ -114,7 +116,6 @@ public class DocumentCollection
super();
}


public DocumentDescriptorFactory getDocumentDescriptorFactory()
{
return documentDescriptorFactory;
Expand Down Expand Up @@ -634,6 +635,22 @@ public void invalidateRootDocument(@NonNull final DocumentPath documentPath)

public Document duplicateDocument(final DocumentPath fromDocumentPath)
{
// NOTE: assume running out of transaction

// Clone the document in transaction.
// One of the reasons of doing this is because for some documents there are events which are triggered on each change (but on trx commit).
// If we would run out of transaction, those events would be triggered 10k times.
// e.g. copying the AD_Role. Each time a record like AD_Window_Access is created, the UserRolePermissionsEventBus.fireCacheResetEvent() is called.
final ITrxManager trxManager = Services.get(ITrxManager.class);
final DocumentPath toDocumentPath = trxManager.call(ITrx.TRXNAME_ThreadInherited, () -> duplicateDocumentInTrx(fromDocumentPath));

return forDocumentReadonly(toDocumentPath, NullDocumentChangesCollector.instance, Function.identity());
}

private DocumentPath duplicateDocumentInTrx(final DocumentPath fromDocumentPath)
{
// NOTE: assume it's already running in transaction

final TableRecordReference fromRecordRef = getTableRecordReference(fromDocumentPath);

final Object fromModel = fromRecordRef.getModel(PlainContextAware.newWithThreadInheritedTrx());
Expand All @@ -652,7 +669,7 @@ public Document duplicateDocument(final DocumentPath fromDocumentPath)
childCRS.copyRecord(fromPO, ITrx.TRXNAME_ThreadInherited);

final DocumentPath toDocumentPath = DocumentPath.rootDocumentPath(fromDocumentPath.getWindowId(), DocumentId.of(toPO.get_ID()));
return forDocumentReadonly(toDocumentPath, NullDocumentChangesCollector.instance, Function.identity());
return toDocumentPath;
}

public BoilerPlateContext createBoilerPlateContext(final DocumentPath documentPath)
Expand Down

0 comments on commit 58de729

Please sign in to comment.