automatic update of graphiti diagrams in case of changes in the datamodel - eclipse-rcp

I have an EMF Datamodel and represent it with the framework "Graphiti".
In case of changes in the datamodel the method "updateNeeded()" in my UpdateFeature is randomly called or not. Therefor I have a listener. This listener calls the method "update()" in case of changes.
In the method update I can define the differences between datamodel and diagram. But if I want to add or change anything to the diagram an exception is thrown.
Has anyone an idea how I could autoupdate the diagram?
Here is my examplecode in the listener:
UpdateContext updateContext = new UpdateContext(getDiagram().getChildren().get(0).getGraphicsAlgorithm().getPictogramElement());
IUpdateFeature updateFeature = getFeatureProvider().getUpdateFeature(updateContext);
updateFeature.update(updateContext);
and the exception:
!ENTRY org.eclipse.ui 4 0 2013-07-11 13:36:43.886
!MESSAGE Unhandled event loop exception
!STACK 0
org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.IllegalStateException: Cannot modify resource set without a write transaction)
Caused by: java.lang.IllegalStateException: Cannot modify resource set without a write transaction
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.assertWriting
Regards, Juliane

In Graphiti you need to execute changes to diagram within an EMF transaction.
You can do that by executing your code as follows:
TransactionalEditingDomain domain = TransactionUtils.getEditingDomain(diagram);
domain.getCommandStack().execute(new RecordingCommand(domain) {
public void doExecute() {
UpdateContext updateContext = new UpdateContext(getDiagram().getChildren().get(0).getGraphicsAlgorithm().getPictogramElement());
IUpdateFeature updateFeature = getFeatureProvider().getUpdateFeature(updateContext);
updateFeature.update(updateContext);
}
});
Hope this helps

Related

How do I make data calls from different Blazor components simultaneously?

I'm new to Blazor and trying to make a page with several separate components to handle a massive form. Each individual component covers a part of the form.
The problem I'm facing is that each of my components needs access to data from the back-end, and not every component uses the same data. When the page loads, each components makes an attempt to fetch data from the server, which causes a problem with Entity Framework.
A second operation started on this context before a previous operation
completed. This is usually caused by different threads using the same
instance of DbContext.
This is obviously caused by the fact that my components are initialized at the same time, and all make their attempt to load the data simultaneously. I was under the impression that the way DI is set up in Blazor, this wouldn't be a problem, but it is.
Here are the components in my template:
<CascadingValue Value="this">
<!-- BASE DATA -->
<CharacterBaseDataView />
<!-- SPECIAL RULES -->
<CharacterSpecialRulesView />
</CascadingValue>
Here is how my components are initialized:
protected async override Task OnInitializedAsync()
{
CharacterDetailsContext = new EditContext(PlayerCharacter);
await LoadCharacterAsync();
}
private async Task LoadCharacterAsync()
{
PlayerCharacter = await PlayerCharacterService.GetPlayerCharacterAsync(ViewBase.CharacterId.Value);
CharacterDetailsContext = new EditContext(PlayerCharacter);
}
When two components with the above code are in the same view, the mentioned error occurs. I thread using the synchronous version "OnInitialized()" and simply discarding the task, but that didn't fix the error.
Is there some other way to call the data so that this issue doesn't occur? Or am I going about this the wrong way?
You've hit a common problem in using async operations in EF - two or more operations trying to use the same context at once.
Take a look at the MS Docs article about EF DBContexts - there's a section further down specific to Blazor. It explains the use of a DbContextFactory and CreateDbContext to create contexts for units-of-work i.e. one context per operation so two async operations each have a separate context.
Initially to solve the threading issues, I used DbContextFactory to create contexts for each operation - however this resulted in database in-consistency issues across components, and I realised I need change tracking across components.
Therefore instead, I keep my DbContext as scoped, and I don't create a new context before each operation.
I then adapted my OnInitializedAsync() methods to check if the calls to the database have completed, before making these calls through my injected services. This works really well for my app:
#code {
static Semaphore semaphore;
//code ommitted for brevity
protected override async Task OnInitializedAsync()
{
try
{
//First open global semaphore
semaphore = Semaphore.OpenExisting("GlobalSemaphore");
while (!semaphore.WaitOne(TimeSpan.FromTicks(1)))
{
await Task.Delay(TimeSpan.FromSeconds(1));
}
//If while loop is exited or skipped, previous service calls are completed.
ApplicationUsers = await ApplicationUserService.Get();
}
finally
{
try
{
semaphore.Release();
}
catch (Exception ex)
{
Console.WriteLine("ex.Message");
}
}
}

Concurrent modification should not be logged as ERROR?

We have an application running on a Wildfly 17. I have a scenario, which occurs occasionally, in which two background threads are accessing the same entity:
Thread A deletes the entity (for good reason)
Thread B is working on slightly older data and attempts to update the entity
When thread B is the later of the two, it fails due to the concurrent modification. This works correctly. It is retried automatically and finds that nothing needs to be done anymore (because the entity has been deleted). That is the intended behavior, when these two threads collide. All is fine!
However I find that this is logged as ERROR by CMTTxInterceptor:
2020-03-31 16:51:35,463 +0200 ERROR: as.ejb3.invocation - WFLYEJB0034: EJB Invocation failed on component ... for method ... throws ...:
javax.ejb.EJBTransactionRolledbackException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:364) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:144) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
...
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_171]
at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118)
Caused by: javax.persistence.OptimisticLockException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1729) [hibernate-entitymanager.jar:5.0.12.Final]
... at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:185) [wildfly-ejb3-17.0.1.Final.jar:17.0.1.Final]
... 262 more
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:67) [hibernate-core.jar:5.0.12.Final]
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:54) [hibernate-core.jar:5.0.12.Final]
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:46) [hibernate-core.jar:5.0.12.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3261) [hibernate-core.jar:5.0.12.Final]
...
It seems to me, that this log is incorrect, mostly because this is not an ERROR. Concurrent modification is something normal, that is to be expected - and that our application logic handles. This log will distract my colleagues at the hotline.
Do you agree that the logging is incorrect, or am I missing something?
I think I will disable logging for "as.ejb3.invocation".
In your case this exception was thrown because Hibernate detected that the entity previously fetched from database was changed (deleted) during the current transaction. So, there is nothing to update.
In this specific case I think you can ignore or swallow the exception. In other cases, it may be good to know about this exception, so I recommend swallow the exception but don’t disable as a whole on log level.

Eclipse 4 rcp load layout not works with binding context

I have an application, in which I can save the load perspective layout.
Everything works until I add Binding Context to any Part. If I set Binding Context to part, then save layout, then close application and try to load layout in opened application again I get exception:
!ENTRY org.eclipse.e4.ui.workbench.swt 4 2 2016-10-16 20:54:37.922
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.e4.ui.workbench.swt".
!STACK 0
org.eclipse.e4.core.di.InjectionException: java.lang.IllegalArgumentException: A handle object may not have a null identifier
at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:65)
at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier$ContextInjectionListener.update(ContextObjectSupplier.java:90)
at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:111)
at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:343)
at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:358)
at org.eclipse.e4.core.internal.contexts.EclipseContext.activate(EclipseContext.java:663)
at org.eclipse.e4.core.internal.contexts.EclipseContext.activateBranch(EclipseContext.java:669)
at org.eclipse.e4.ui.internal.workbench.swt.ShellActivationListener$1.run(ShellActivationListener.java:95)
here is my steps:
test handler class:
public class Test {
#Execute
public void execute(EPartService partService) {
System.out.println("Test handler");
}
}
Create handler:
Then create Binding Contect, Binding table with KeyBinding
finally add BindingContext to part:
Loading and saving layout code is same as in this tutorial Model persistence article 3
Maybe someone knows what problem can be and is there are any solution?

org.eclipse.swt.SWTException: Invalid thread access from HandledContributionItem

I know there are lots of such questions here and most of them are answered. But the answers just won't solve my case.
I'm working on an eclipse plugin project, have a customized project type which can be either run or debugged. I have implemented the run and debug function and everything I expected are displayed on the screen, except the console shows an exception:
!ENTRY org.eclipse.e4.ui.workbench 4 0 2015-04-28 23:31:17.410
!MESSAGE Internal error during tool item enablement updating, this is only logged once per tool item.
!STACK 0
org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4441)
at org.eclipse.swt.SWT.error(SWT.java:4356)
at org.eclipse.swt.SWT.error(SWT.java:4327)
at org.eclipse.swt.widgets.Widget.error(Widget.java:783)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:574)
at org.eclipse.swt.widgets.Widget.getData(Widget.java:874)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.updateIcons(HandledContributionItem.java:546)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.update(HandledContributionItem.java:440)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.update(HandledContributionItem.java:430)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem$3.run(HandledContributionItem.java:168)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.updateItemEnablement(HandledContributionItem.java:196)
at org.eclipse.e4.ui.workbench.renderers.swt.ToolItemUpdater.updateContributionItems(ToolItemUpdater.java:39)
at org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRenderer$8.changed(ToolBarManagerRenderer.java:367)
at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:110)
at org.eclipse.e4.core.internal.contexts.EclipseContext.processScheduled(EclipseContext.java:338)
at org.eclipse.e4.core.internal.contexts.EclipseContext.set(EclipseContext.java:352)
at org.eclipse.ui.internal.services.EvaluationService.contextEvaluate(EvaluationService.java:139)
at org.eclipse.ui.internal.services.EvaluationService.addSourceProvider(EvaluationService.java:180)
at org.eclipse.debug.internal.ui.contexts.DebugContextSourceProvider.<init>(DebugContextSourceProvider.java:51)
at org.eclipse.debug.internal.ui.contexts.DebugWindowContextService.<init>(DebugWindowContextService.java:62)
at org.eclipse.debug.internal.ui.contexts.DebugContextManager.createService(DebugContextManager.java:163)
at org.eclipse.debug.internal.ui.contexts.DebugContextManager.getContextService(DebugContextManager.java:221)
at org.eclipse.debug.internal.ui.views.ViewContextService.<init>(ViewContextService.java:620)
at org.eclipse.debug.internal.ui.views.ViewContextManager.windowOpened(ViewContextManager.java:93)
at org.eclipse.debug.internal.ui.views.ViewContextManager.<init>(ViewContextManager.java:55)
at org.eclipse.debug.internal.ui.views.ViewContextManager.getDefault(ViewContextManager.java:44)
at org.eclipse.debug.internal.ui.contexts.DebugContextManager.getDefault(DebugContextManager.java:150)
at org.eclipse.debug.ui.DebugUITools.getDebugContextManager(DebugUITools.java:1068)
at org.eclipse.debug.internal.ui.sourcelookup.SourceLookupService.<init>(SourceLookupService.java:40)
at org.eclipse.debug.internal.ui.sourcelookup.SourceLookupManager.windowOpened(SourceLookupManager.java:91)
at org.eclipse.debug.internal.ui.sourcelookup.SourceLookupManager.<init>(SourceLookupManager.java:41)
at org.eclipse.debug.internal.ui.sourcelookup.SourceLookupManager.getDefault(SourceLookupManager.java:53)
at org.eclipse.debug.internal.ui.DebugUIPlugin.initializeLaunchListeners(DebugUIPlugin.java:935)
at org.eclipse.debug.internal.ui.DebugUIPlugin.launchAdded(DebugUIPlugin.java:920)
at org.eclipse.debug.internal.core.LaunchManager$LaunchNotifier.run(LaunchManager.java:451)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.debug.internal.core.LaunchManager$LaunchNotifier.notify(LaunchManager.java:438)
at org.eclipse.debug.internal.core.LaunchManager.fireUpdate(LaunchManager.java:1044)
at org.eclipse.debug.internal.core.LaunchManager.addLaunch(LaunchManager.java:708)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:834)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:739)
at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1039)
at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1256)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
My codes are as following: In LaunchShortCut.java I have
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
Shell activeShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
if(DebugUITools.openLaunchConfigurationDialog(activeShell, config, group, null) == Window.CANCEL){
return;
}
}
});
This trigger the LaunchConfigurationWindow, and does not show any exception in console. When I hit the "run" in this window, the process stops at the first line in the following code where I have a breakpoint, and shows the exception in the console.
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
//clear old output
HTMLOutput htmloutput = (HTMLOutput) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("my.view.id");
}
}
From the stack trace of the exception I don't see anything related to my code. If I let the program go on running, everything is fine, I don't see any trouble this exception causes, but I just can't figure what's it about and can't even stop it from showing up. Please help me on this issue.
It seems that you've hit a bug in Eclipse. The same stacktrace is described in Bug 445560. Chances are that the workaround described in this bug report (see comment 4) also helps in your case:
As current local workaround for this issue I've added in our rcp code an early call to DebugUITools.getDebugContextManager() from the UI thread.
Ugly, and should not be needed, but it avoids the failures seen when launching for the first time.

Unable to Load persisted workflow with work flow Instance Id in WF 4.5

'EnvironmentLocationReference' is not of type 'InternalState'. When loading this instance you must ensure that the activity with name 'EnvironmentLocationReference' implements 'InternalState'.
Please help to resolve this.
Getting Exception in
workflowapplication wfapp=new workflowapplication(new workflowDefinition);
wfappp.Load(wfId, new TimeSpan(0, 0, 5));
wfid(workflow id) which is saved in persistance database