Cannot modify resource set without a write transaction [message #724465] |
Mon, 12 September 2011 08:29  |
Eclipse User |
|
|
|
Hi,
I know that i have to wrap every model change into an EMF transaction. I have done that, but I get that error anyway.
How to produce the error?
- I have a RCP with the Graphiti Editor. On Startup a default model file is created and saved to disk, which works fine
- Add a model element (ConfirmDialog)
- Save
Then this error occurs (BUT the model is actually saved correctly, so the new ConfirmDialog appears in the model file)
!ENTRY org.eclipse.graphiti.ui 0 0 2011-09-12 14:13:47.809
!MESSAGE The following resources could not be saved:
URI: platform:/resource/tempEditorProject/diagrams/newDiagram.model, cause:
java.lang.IllegalStateException: Cannot modify resource set without a write transaction
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.assertWriting(TransactionChangeRecorder.java:348)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.appendNotification(TransactionChangeRecorder.java:302)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.processObjectNotification(TransactionChangeRecorder.java:284)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.notifyChanged(TransactionChangeRecorder.java:240)
at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:380)
at org.eclipse.emf.ecore.util.EcoreEList.dispatchNotification(EcoreEList.java:255)
at org.eclipse.emf.common.notify.impl.NotifyingListImpl.addUnique(NotifyingListImpl.java:300)
at org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:307)
at org.eclipse.emf.common.util.BasicEMap.put(BasicEMap.java:591)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:292)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:270)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:993)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService$1$1.run(EmfService.java:250)
at org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.runExclusive(TransactionalEditingDomainImpl.java:328)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService$1.run(EmfService.java:261)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1957)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:273)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:211)
at org.eclipse.graphiti.ui.internal.editor.DiagramEditorBehavior$3.execute(DiagramEditorBehavior.java:500)
at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
!STACK 0
java.lang.RuntimeException
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:275)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:211)
at org.eclipse.graphiti.ui.internal.editor.DiagramEditorBehavior$3.execute(DiagramEditorBehavior.java:500)
at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
!ENTRY org.eclipse.graphiti.ui 4 0 2011-09-12 14:13:47.809
!MESSAGE The following resources could not be saved:
URI: platform:/resource/tempEditorProject/diagrams/newDiagram.model, cause:
java.lang.IllegalStateException: Cannot modify resource set without a write transaction
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.assertWriting(TransactionChangeRecorder.java:348)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.appendNotification(TransactionChangeRecorder.java:302)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.processObjectNotification(TransactionChangeRecorder.java:284)
at org.eclipse.emf.transaction.impl.TransactionChangeRecorder.notifyChanged(TransactionChangeRecorder.java:240)
at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:380)
at org.eclipse.emf.ecore.util.EcoreEList.dispatchNotification(EcoreEList.java:255)
at org.eclipse.emf.common.notify.impl.NotifyingListImpl.addUnique(NotifyingListImpl.java:300)
at org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:307)
at org.eclipse.emf.common.util.BasicEMap.put(BasicEMap.java:591)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:292)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:270)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:206)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1406)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:993)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService$1$1.run(EmfService.java:250)
at org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.runExclusive(TransactionalEditingDomainImpl.java:328)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService$1.run(EmfService.java:261)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1957)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:273)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:211)
at org.eclipse.graphiti.ui.internal.editor.DiagramEditorBehavior$3.execute(DiagramEditorBehavior.java:500)
at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
!STACK 0
java.lang.RuntimeException
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:275)
at org.eclipse.graphiti.ui.internal.services.impl.EmfService.save(EmfService.java:211)
at org.eclipse.graphiti.ui.internal.editor.DiagramEditorBehavior$3.execute(DiagramEditorBehavior.java:500)
at org.eclipse.ui.actions.WorkspaceModifyOperation$1.run(WorkspaceModifyOperation.java:106)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ui.actions.WorkspaceModifyOperation.run(WorkspaceModifyOperation.java:118)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
The problem has to be in the Create feature of the ConfirmDialog or the saveToModelFile() method. I show you the code snippets:
ConfirmDialog:public Object[] create(ICreateContext context) {
// create ConfirmDialog with title and message
final ConfirmDialog newConfirmDialog = EMFFactory.eINSTANCE.createConfirmDialog();
final StringLiteral defaultTitle = EMFFactory.eINSTANCE.createStringLiteral();
final StringLiteral defaultMessage = EMFFactory.eINSTANCE.createStringLiteral();
defaultTitle.setValue("Title");
newConfirmDialog.setTitle(defaultTitle);
defaultMessage.setValue("Message");
newConfirmDialog.setMessage(defaultMessage);
//Use the following instead of the above line to store the model
//data in a seperate file parallel to the diagram file
try {
try {
DiagramUtil.saveToModelFile(newConfirmDialog , getDiagram(), getDiagramEditor().getEditingDomain());
} catch (IOException e) {
e.printStackTrace();
}
} catch (CoreException e) {
e.printStackTrace();
}
// do the add
addGraphicalRepresentation(context, newConfirmDialog);
// activate direct editing after object creation
getFeatureProvider().getDirectEditingInfo().setActive(true);
// return newly created business object(s)
return new Object[] { newConfirmDialog};
}
Here the saveToModelFile() method. (Most of it is copied from org.eclipse.graphiti.examples.tutorial.TutorialUtil.saveToModelFile)public static void saveToModelFile(final EObject obj, final Diagram d,
TransactionalEditingDomain editingDomain) throws CoreException,
IOException {
URI uri = d.eResource().getURI();
uri = uri.trimFragment();
uri = uri.trimFileExtension();
uri = uri.appendFileExtension("model");
ResourceSet rSet = d.eResource().getResourceSet();
final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
.getRoot();
IResource file = workspaceRoot.findMember(uri.toPlatformString(true));
if (file == null || !file.exists()) {
Resource createResource = rSet.createResource(uri);
createResource.save(Collections.emptyMap());
createResource.setTrackingModification(true);
}
final Resource resource = rSet.getResource(uri, true);
if (obj instanceof DiagramDialog) {
final CommandStack commandStack = editingDomain.getCommandStack();
commandStack.execute(new RecordingCommand(editingDomain) {
@Override
protected void doExecute() {
//Save DiagramDialog at proper position
((DocumentRoot) resource.getContents().get(0)).getProcedure().get(0).add((DiagramDialog ) obj);
}
});
}
}
Any ideas? I try to solve this for about 3 hours now and i am running out of ideas...
thx!
[Updated on: Mon, 12 September 2011 08:58] by Moderator
|
|
|
|
|
Re: Cannot modify resource set without a write transaction [message #793023 is a reply to message #792924] |
Tue, 07 February 2012 12:21   |
Eclipse User |
|
|
|
Am 07.02.2012 16:17, schrieb Christian B:
> I still haven't solved this problen, any ideas?
Hi, actually I think don't get your problem right, but nontheless my 2
cents.
Your problem is that you execute a write transaction from within another
write transaction. I.e. the create-Method in the CreateFeature is
performed within a write transaction and you try to execute another one
while in that transaction. Thus the framework throws an Exception.
If you create the businessmodel alongside the diagrammodel and link an
object in the buisnessmodel to the diagram. You don't need the save util
at all. The editor will handle the save of the elements on his own based
on the TransactionalEditingDomain, which will contain both models
because of the cross reference from the Diagram to the
buisnessmodelelement.
You can do that in your wizard that creates the new Model.
It's rather simple. In your performFinish-Method you only need to call
the FileUtil twice.
....
<<BUSINESSMODELELEMENT>> = <<create RootBusinessmodel with factory>>
FileService.createEmfFileForDiagram(uriCore, <<BUSINESSMODELELEMENT>>);
TransactionalEditingDomain domain = FileService
.createEmfFileForDiagram(uri, diagram);
After that you can link the diagram to the buisnessmodel like that:
Assert.isNotNull(diagram.getDiagramTypeId());
String providerId = GraphitiUi.getExtensionManager()
.getDiagramTypeProviderId(diagram.getDiagramTypeId());
Assert.isNotNull(providerId);
domain.getCommandStack().execute(new LinkCoreModelCommand(domain,
diagram, <<BUSINESSMODELELEMENT>>, providerId));
The LinkCoreModelCommand looks like that:
public class LinkCoreModelCommand extends RecordingCommand {
private Diagram diagram;
private EObject coreModel;
private String providerId;
public LinkCoreModelCommand(TransactionalEditingDomain domain,
Diagram diagram, EObject coreModel, String providerId) {
super(domain);
this.diagram = diagram;
this.coreModel = coreModel;
this.providerId = providerId;
}
@Override
protected void doExecute() {
IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager()
.createDiagramTypeProvider(diagram, providerId);
IFeatureProvider featureProvider = dtp.getFeatureProvider();
featureProvider.link(diagram, coreModel);
}
}
Cheers Veit
|
|
|
|
|
Re: Cannot modify resource set without a write transaction [message #900071 is a reply to message #900032] |
Fri, 03 August 2012 15:41  |
Eclipse User |
|
|
|
My solution was to not propagate the notifications from the xmlns prefix map feature in my DocumentRootImpl like so:
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
@SuppressWarnings("serial")
public EMap<String, String> getXMLNSPrefixMap() {
if (xMLNSPrefixMap == null) {
xMLNSPrefixMap = new EcoreEMap<String, String>(EcorePackage.Literals.ESTRING_TO_STRING_MAP_ENTRY,
EStringToStringMapEntryImpl.class, null) {
{
initializeDelegateEList();
}
@Override
protected void initializeDelegateEList() {
delegateEList = new DelegateEObjectContainmentEList<Entry<String, String>>(entryClass,
DocumentRootImpl.this, SwitchyardPackage.DOCUMENT_ROOT__XMLNS_PREFIX_MAP) {
@Override
protected void dispatchNotification(Notification notification) {
// don't forward the notification
}
};
}
};
}
return xMLNSPrefixMap;
}
|
|
|
Powered by
FUDForum. Page generated in 0.05514 seconds