Andy King
Andy King

Reputation: 1572

GWT Request Factory and Editor Framework Exception

When attempting to edit a new (proxy) entity using RequestFactoryEditorDriver.edit() I am getting the following error: "Exception caught: Attempting to edit an EntityProxy previously edited by another RequestContext". I am fairly sure that this is a result of my misunderstanding of the request factory/editor framework architecture. Here is the editor code that I think pertains to this problem:

public class OrgMaintenanceWidget extends Composite implements Editor<IOrgProxy> {
... other fields ...
private IOrgEditorDriver _orgEditorDriver;
interface IOrgEditorDriver extends RequestFactoryEditorDriver<IOrgProxy, OrgMaintenanceWidget> {}
public OrgMaintenanceWidget(final IClientFactory clientFactory) {
  ... widget initialization ...
  _orgEditorDriver = GWT.create(IOrgEditorDriver.class);
  _orgEditorDriver.initialize(_clientFactory.getRequestFactory().getEventBus(),
                              _clientFactory.getRequestFactory(), this);
}
@UiHandler("newButton")
public void onNewButtonClick(final ClickEvent clickEvent) {
  _org = _clientFactory.getCache().getOrgCache().newOrg();
  _orgEditorDriver.edit(_org, _clientFactory.getRequestFactory().orgRequestContext());
}
...
}

It's the "_orgEditorDriver.edit()" line that causes the exception. The "newOrg()" method is:

public IOrgProxy newOrg() {
  return _clientFactory.getRequestFactory().orgRequestContext().create(IOrgProxy.class);
}

The RequestFactory is simply:

public interface IRequestFactory extends RequestFactory {
IOrgRequestContext orgRequestContext();
}

I am sure that I'm missing something fundamental about editing a new entity. When I edit an existing entity everything is fine ... the UI components are populated automatically, and flushing the editor back to the entity works very nicely. Here's the code that initiates editing for an existing entity:

@UiHandler("newButton")
public void onNewButtonClick(final ClickEvent clickEvent) {
  _org = _clientFactory.getCache().getOrgCache().newOrg();
  _orgEditorDriver.edit(_org, _clientFactory.getRequestFactory().orgRequestContext());
}

Any help would be greatly appreciated, and I'll try to publish any lessons learned.

Upvotes: 1

Views: 1052

Answers (2)

Piotr Sobczyk
Piotr Sobczyk

Reputation: 6583

This code:

_clientFactory.getRequestFactory().orgRequestContext().create(IOrgProxy.class);

Means:

  1. Create new orgRequestContext()
  2. Create new IOrgProxy using this context
  3. Edit new IOrgProxy using this context, because as docs say: "Returns a new mutable proxy that this request can carry to the server, perhaps to be persisted.", it means that the proxy is edited by this request.

This code:

_orgEditorDriver.edit(_org, _clientFactory.getRequestFactory().orgRequestContext());

Means:

  1. Again, create new orgRequestContext() (because each invocation of getRequestFactory().orgRequestContext() provides new instance of orgRequestContext()

  2. "Start driving the Editor and its sub-editors with data." as docs say. But as a part of it, use passed orgRequestContext() to edit passed IOrgProxy instance, so that the proxy is editable.

  3. Because the proxy was already edited while created by other RequestContext, you get the exception, because there is fundamental rule in RequestFactory, that proxy can be edited only by one RequestContext.

    See also this thread.

Upvotes: 2

&#220;mit
&#220;mit

Reputation: 17499

I think you can't create an object with one RequestContext and then edit it with another one. So you can solve this in two ways:

  • Persist the created object with the RequestContext you used when you created the object. The save method should return the persisted object and this persisted object can be passed to the editor with a fresh new RequestContext
  • Somewhere save the RequestContext you used for creating the object and pass it to the edit function of your Driver

Solution two could look something like this:

@UiHandler("newButton")
public void onNewButtonClick(final ClickEvent clickEvent) {
  IOrgRequestContext ctx = _clientFactory.getRequestFactory().orgRequestContext();
  _org = ctx.create(IOrgProxy.class);
  _orgEditorDriver.edit(_org,ctx );
}

Upvotes: 1

Related Questions