我在 GWT 2.5 中使用(并且是新手)RequestFactory,在 AppEngine 数据存储区中使用具有一对多关系的 JDO 实体。我刚刚开始使用 GWT RequestFactoryEditorDriver 来显示/编辑我的对象。
Driver 可以很好地遍历我的对象,并正确显示它们。但是,当我尝试编辑“相关”对象上的值时,更改不会持久保存到数据存储区。
当我更改b.name
我的 UI 并单击“保存”时,我注意到只调用了 A 的persist()
调用。B 的 persist() 永远不会被调用。如何让 editorDriver 在 ARequest 和 BRequest 请求上下文中触发?(因为我想要的是InstanceRequest<AProxy,Void> persist()
在我的编辑仅针对 B 对象时调用 B。)
此外,AFAICT,如果我在 BProxy 上有一个编辑器,则编辑器显示的任何对象 b(并遵循编辑器合同)都应由驱动程序自动“context.edit(b)”编辑以使其可变。但是,在我的情况下,“上下文”是一个 ARequest,而不是 BRequest。
我是否必须像这里提到的那样制作一个 ValueAwareEditor:GWT Editor framework
并在调用中创建一个新的 BRequestflush()
并触发它,以便在触发 ARequest 之前对 B 的更改单独保留在 BRequest 中?
editorDriver.getPaths()
给我:“bs”
此外,驱动程序肯定会看到 B 属性的更改,因为editorDriver.isChanged()
在我 fire() 上下文之前返回 true。
我的客户端或服务器端日志没有错误,注释处理器运行时没有警告。
这是我设置驱动程序的方法:
editorDriver = GWT.create(Driver.class);
editorDriver.initialize(rf, view.getAEditor());
final ARequest aRequest = rf.ARequest();
final Request<List<AProxy>> aRequest = aRequest.findAByUser(loginInfo.getUserId());
String[] paths = editorDriver.getPaths();
aRequest.with(paths).fire(new Receiver<List<AProxy>>() {
@Override
public void onSuccess(List<AProxy> response) {
AProxy a = response.get(0);
ARequest aRequest2 = rf.aRequest();
editorDriver.edit(a, aRequest2);
aRequest2.persist().using(a);
}
});
这是我的实体的外观:
public abstract class PersistentEntity {
public Void persist() {
PersistenceManager pm = getPersistenceManager();
try {
pm.makePersistent(this);
} finally {
pm.close();
}
return null;
}
public Void remove() {
PersistenceManager pm = getPersistenceManager();
try {
pm.deletePersistent(this);
} finally {
pm.close();
}
return null;
}
}
@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Version(strategy=VersionStrategy.VERSION_NUMBER, column="VERSION",
extensions={@Extension(vendorName="datanucleus", key="field-name", value="version")})
public class A extends PersistentEntity {
... (Id, version omitted for brevity)
@Persistent
private String name;
@Persistent
private List<B> bs;
public String getName() {
return name;
}
...
public void setName(String name) {
this.name = name;
}
public List<B> getBs() {
return bs;
}
public void setBs(List<B> bs) {
this.bs = bs;
}
}
... (same annotations as above omitted for brevity)
public class B extends PersistentEntity {
... (Id, version omitted for brevity)
@Persistent
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以下是代理:
@ProxyFor(A.class)
public interface AProxy extends EntityProxy {
String getName();
List<BProxy> getBs();
void setName(String name);
void setBs(List<BProxy> bs);
}
@ProxyFor(B.class)
public interface BProxy extends EntityProxy {
String getName();
void setName(String name);
}
这是我的服务存根:
@Service(A.class)
public interface ARequest extends RequestContext {
Request<List<A>> findAByUser(String userId);
InstanceRequest<AProxy, Void> persist();
InstanceRequest<AProxy, Void> remove();
}
@Service(B.class)
public interface BRequest extends RequestContext {
Request<List<A>> findB(String key);
InstanceRequest<BProxy, Void> persist();
InstanceRequest<BProxy, Void> remove();
}
编辑:我现在更改了我的 ARequest 接口和服务实现以支持“saveAndReturn”方法,这样我就可以在服务器端递归地“持久化”“a”:
Request<UserSandboxProxy> saveAndReturn(AProxy aProxy);
我现在发现,当我“刷新”我的 RequestFactoryEditorDriver 时,客户端上下文对象具有我的新“b.name”值。但是,如果我调用“context.fire()”并在服务器端检查我的“saveAndReturn”方法,则生成的服务器端对象“a”,就在我“持久化”它之前,不包含对“ b.name”在列表的任何项目上。
为什么会发生这种情况?我如何调试为什么这个客户端信息不通过线路到达服务器?
我考虑过、尝试过并排除的选项:
1) 确保 APT 已经运行,并且 Proxy 或 Service 接口上没有警告/错误
2) 确保我的代理在 AProxy 中确实有一个有效的设置器用于列表