RequestFactory理论:为什么经常调用Locator 。find()?

我是RequestFactory的新手,但在Thomas Broyer的慷慨帮助下,在审阅了下面的文档后,它变得更好:)

  • RequestFactory入门
  • 要求工厂搬运零件
  • GWT 2.4中的RequestFactory更改

但是你能解释一下为什么经常会不必要地(在我看来)不必要地调用Locator.find()吗?

在我的示例项目中,我有两个维护父子关系的实体Organization和Person。 当我获取组织Objectify时自动获取子Person。 我还在我的服务层saveOrganizationsaveOrganization中创建了两个加载和持久化对象的方法。

现在考虑两种情况:

当我在客户端调用findOrganizationById ,在服务器端进行调用:

 OrderDao.findOrganizationById(1) PojoLocator.getId(Key(Organization(1))) PojoLocator.getId(Key(Organization(1)/Person(2))) PojoLocator.getId(Key(Organization(1))) PojoLocator.find(Key(Organization(1))) PojoLocator.getId(Key(Organization(1)/Person(2))) PojoLocator.find(Key(Organization(1)/Person(2))) 

通过调用OrderDao.findOrganizationById我已经收到完整的对象图。 除了那之外,为什么要.find两次.find ? 数据存储的额外负载花了我钱。 当然我会缓存它,但修复它会很好。 我怎样才能避免这些额外的电话?

当我通过在客户端中调用saveOrganization来保存对象时,会发生类似的事情。 以下调用发生在服务器端:

 PojoLocator.find(Key(Organization(1))) PojoLocator.find(Key(Organization(1)/Person(2))) OrderDao.saveOrganization(1) PojoLocator.getId(Key(Organization(1))) PojoLocator.find(Key(Organization(1))) PojoLocator.getId(Key(Organization(1)/Person(2))) PojoLocator.find(Key(Organization(1)/Person(2))) 

我可以理解更新它之前需要从DataStore中获取两个对象。 RequestFactory将增量发送到服务器,因此在持久化之前需要拥有整个对象。 自从我一次加载完整的图形以后,最好不要进行第二次调用,这是PojoLocator.find(Key(Organization(1)/Person(2)))持久化之后 ,我真的无法理解对.find()调用的需求。

想法?

我的代理人

 @ProxyFor(value = Organization.class, locator = PojoLocator.class) public interface OrganizationProxy extends EntityProxy { public String getName(); public void setName(String name); public String getAddress(); public void setAddress(String address); public PersonProxy getContactPerson(); public void setContactPerson(PersonProxy contactPerson); public EntityProxyId stableId(); } @ProxyFor(value = Person.class, locator = PojoLocator.class) public interface PersonProxy extends EntityProxy { public String getName(); public void setName(String name); public String getPhoneNumber(); public void setPhoneNumber(String phoneNumber); public String getEmail(); public void setEmail(String email); public OrganizationProxy getOrganization(); public void setOrganization(OrganizationProxy organization); } 

我的服务

 public interface AdminRequestFactory extends RequestFactory { @Service(value = OrderDao.class, locator = InjectingServiceLocator.class) public interface OrderRequestContext extends RequestContext { Request saveOrganization(OrganizationProxy organization); Request findOrganizationById(long id); } OrderRequestContext contextOrder(); } 

最后我的定位器

 public class PojoLocator extends Locator { @Inject Ofy ofy; @Override public DatastoreObject create(Class clazz) { try { return clazz.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @Override public DatastoreObject find(Class clazz, String id) { Key key = Key.create(id); DatastoreObject load = ofy.load(key); return load; } @Override public Class getDomainType() { return null; // Never called } @Override public String getId(DatastoreObject domainObject) { Key key = ofy.fact().getKey(domainObject); return key.getString(); } @Override public Class getIdType() { return String.class; } @Override public Object getVersion(DatastoreObject domainObject) { return domainObject.getVersion(); } } 

最后的getIdfind对是Locator#isLive的默认实现:它假定一个对象是实时的 (即仍然存在于数据存储中),如果通过它的ID找到它返回一个非空值。

RF在构造响应时检查它在请求/响应期间看到的每个EntityProxy活跃性 ,告诉客户端何时删除了一个实体(在客户端,它然后用DELETE 写操作触发EntityProxyChange事件)。

如果可以提供更优化的实现,您当然可以在Locator覆盖isLive