Google app engine 请求工厂GWT编辑器更改isn';t持久化相关的JDO实体
我正在AppEngine数据存储上使用GWT2.5中的RequestFactory(也是新的)和具有一对多关系的JDO实体。我刚刚开始使用GWT RequestFactoryEditorDriver来显示/编辑我的对象 驱动程序可以很好地遍历我的对象,并正确地显示它们。但是,当我试图编辑“相关”对象上的值时,更改不会持久化到数据存储中 当我在UI上更改Google app engine 请求工厂GWT编辑器更改isn';t持久化相关的JDO实体,google-app-engine,gwt,one-to-many,requestfactory,gwt-editors,Google App Engine,Gwt,One To Many,Requestfactory,Gwt Editors,我正在AppEngine数据存储上使用GWT2.5中的RequestFactory(也是新的)和具有一对多关系的JDO实体。我刚刚开始使用GWT RequestFactoryEditorDriver来显示/编辑我的对象 驱动程序可以很好地遍历我的对象,并正确地显示它们。但是,当我试图编辑“相关”对象上的值时,更改不会持久化到数据存储中 当我在UI上更改b.name并单击“保存”时,我注意到只调用了A的persist()调用。永远不会调用B的persist()。如何使editorDriver在AR
b.name
并单击“保存”时,我注意到只调用了A的persist()
调用。永远不会调用B的persist()。如何使editorDriver在ARequest和BRequest请求上下文中同时启动?(因为我想要的是B的InstanceRequest
并在flush()
调用中创建一个新的BRequest并启动它,这样对B的更改就可以在启动一个BRequest之前分别保存在BRequest中
editorDriver.getpath()
为我提供:
“bs”
此外,驱动程序肯定会看到对B属性的更改,因为editorDriver.isChanged()
在触发()上下文之前返回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);
}
});
editorDriver=GWT.create(Driver.class);
初始化(rf,view.getAEditor());
最终ARequest ARequest=rf.ARequest();
最终请求aRequest=aRequest.findAByUser(loginInfo.getUserId());
String[]path=editorDriver.getpath();
带(路径)的aRequest.fire(新接收器(){
@凌驾
成功时公共无效(列表响应){
AProxy a=响应。获取(0);
ARequest aRequest2=rf.ARequest();
editorDriver.edit(a,aRequest2);
aRequest2.persist()。使用(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;
}
}
公共抽象类持久性{
公共图书馆{
PersistenceManager pm=getPersistenceManager();
试一试{
pm.makePersistent(这个);
}最后{
pm.close();
}
返回null;
}
公共空间删除(){
PersistenceManager pm=getPersistenceManager();
试一试{
项目经理(本);
}最后{
pm.close();
}
返回null;
}
}
@PersistenceCapable(identityType=identityType.APPLICATION)
@版本(strategy=VersionStrategy.Version\u编号,column=“Version”,
扩展={@Extension(vendorName=“datanucleus”,key=“field name”,value=“version”)}
公共类A扩展了持久性{
…(Id,为简洁起见省略了版本)
@持久的
私有字符串名称;
@持久的
私人名单;
公共字符串getName(){
返回名称;
}
...
公共void集合名(字符串名){
this.name=名称;
}
公共列表getBs(){
返回bs;
}
公共空间设置(列表B){
这个.bs=bs;
}
}
…(为简洁起见,省略了与上述相同的注释)
公共类B扩展了持久性{
…(Id,为简洁起见省略了版本)
@持久的
私有字符串名称;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.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);
}
@ProxyFor(A.class)
公共接口AProxy扩展了EntityProxy{
字符串getName();
列出getBs();
void setName(字符串名);
无效立根(列表B);
}
@代理(B类)
公共接口BProxy扩展了EntityProxy{
字符串getName();
void setName(字符串名);
}
这是我的服务存根:
@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();
}
@服务(A.class)
公共接口ARequest扩展了RequestContext{
请求findAByUser(字符串userId);
InstanceRequest persist();
InstanceRequest移除();
}
@服务(B级)
公共接口BRequest扩展了RequestContext{
请求findB(字符串键);
InstanceRequest persist();
InstanceRequest移除();
}
编辑:
我现在已经更改了我的ARequest接口和服务实现,以支持“saveAndReturn”方法,这样我就可以在服务器端递归地“持久化”“a”:
Request<UserSandboxProxy> saveAndReturn(AProxy aProxy);
请求保存和返回(AProxy-AProxy);
现在我发现,当我“刷新”我的RequestFactoryEditorDriver时,客户端上下文对象具有我的新“b.name”值。但是,如果我调用“context.fire()”并在服务器端检查我的“saveAndReturn”方法,在我“持久化”它之前,生成的服务器端对象“a”不包含对“b.name”的更改在列表的任何项目上
为什么会发生这种情况?我如何调试为什么这些客户机信息不会通过网络传输到服务器
我考虑、尝试并排除了以下选项:
1) 确保APT已运行,且在代理或服务接口上没有警告/错误
2) 确保我的代理在AProxy中确实有一个有效的setter,用于列表您有使用每个请求的会话模式,以使RequestFactory正常工作。此处有更多详细信息:您是否使用OpenSessionInView(即每个请求的会话)模式?对于JDO,这意味着一个PersistenceManager
跨越整个HTTP请求。@ThomasBroyer不,我不是。现在,我有了这个方法:private static PersistenceManager getPM(){return JDOHelper.getPersistenceManagerFactory(“事务可选”).getPersistenceManager();}
,我为每个DAO操作调用它,比如“persist()”,然后在该操作结束后立即关闭它。但不管“persist()”是否正确完成,我至少应该在调试时看到我的服务器端(pre-persist)obj已经更改了值吗?是否使用OSIV对这一点有何影响?我尝试了从新加载的应用程序中设置“a.name”和“b.name”操作。太棒了!非常感谢,T