【问题标题】:RequestFactory theory: Why is Locator<>.find() being called so often?RequestFactory 理论:为什么经常调用 Locator<>.find()?
【发布时间】:2012-03-17 14:15:47
【问题描述】:

我是 RequestFactory 的新手,但在 Thomas Broyer 的慷慨帮助下,在查看了下面的文档后,情况变得更好了 :)

但是您能否解释一下为什么Locator&lt;&gt;.find() 经常被如此不必要地调用(在我看来)?

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

现在考虑两种情况:

当我在客户端调用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 两次? Datastore 上的额外负载让我花钱。当然我会缓存它,但修复它会很好。如何避免这些额外的调用?

当我在客户端调用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&lt;?&gt;(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<OrganizationProxy> 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<Void> saveOrganization(OrganizationProxy organization);
        Request<OrganizationProxy> findOrganizationById(long id);
    }

    OrderRequestContext contextOrder();
}

最后是我的定位器

public class PojoLocator extends Locator<DatastoreObject, String>
{
    @Inject Ofy ofy;

    @Override
    public DatastoreObject create(Class<? extends DatastoreObject> clazz)
    {
        try
        {
            return clazz.newInstance();
        } catch (InstantiationException e)
        {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Override
    public DatastoreObject find(Class<? extends DatastoreObject> clazz, String id)
    {
        Key<DatastoreObject> key = Key.create(id);
        DatastoreObject load = ofy.load(key);
        return load;
    }

    @Override
    public Class<DatastoreObject> getDomainType()
    {
        return null;    // Never called
    }

    @Override
    public String getId(DatastoreObject domainObject)
    {
        Key<DatastoreObject> key = ofy.fact().getKey(domainObject);
        return key.getString();
    }

    @Override
    public Class<String> getIdType()
    {
        return String.class;
    }

    @Override
    public Object getVersion(DatastoreObject domainObject)
    {
        return domainObject.getVersion();
    }
}

【问题讨论】:

    标签: java gwt requestfactory gwt2


    【解决方案1】:

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

    RF 在构建响应时检查它在请求/响应期间看到的每个EntityProxy活跃度,以便在删除实体时告诉客户端(在客户端,它' d 然后用DELETE 触发EntityProxyChange 事件写操作

    如果你能提供一个更优化的实现,你当然可以在你的Locator 中覆盖isLive

    【讨论】:

    • 在覆盖isLive()之后,我确认这是正确的答案。
    猜你喜欢
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-04
    相关资源
    最近更新 更多