RequestFactory理论:为什么定位器&f?.find()经常被调用? [英] RequestFactory theory: Why is Locator<>.find() being called so often?

查看:130
本文介绍了RequestFactory理论:为什么定位器&f?.find()经常被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是RequestFactory的新手,但是通过 Thomas Broyer 的大量帮助,在查看以下文档之后,更好:)





但是,您能否解释为什么 Locator<> .find()被不必要地(在我看来)被调用了吗?



当我自动获取组织对象 时,提取小孩。
另外,我在我的服务层 c> findOrganizationById
saveOrganization 中创建了两种加载和保留对象的方法。 p>

现在考虑两种情况:



当我调用 findOrganizationById 在客户端跟随呼叫发生在服务器端:

  OrderDao.findOrganizationById(1)
PojoLocator.getId(Key< ?(组织(1)))
PojoLocator.getId(Key<?>(Organization(1)/ Person(2)))
PojoLocator.getId(Key<? (1)))
PojoLocator.find(Key<?>(Organization(1)))
PojoLocator.getId(Key<?>(Organization(1)/ Person(2)))
PojoLocator.find(Key<?>(Organization(1)/ Person(2)))

通过调用 OrderDao.findOrganizationById 我已经收到完整的对象图。为什么要另外调用 .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)))。而且我真的无法理解



想法?



我的代理

  @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
{
请求< Void> saveOrganization(OrganizationProxy组织);
请求< 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);
返回加载;
}

@Override
public Class< DatastoreObject> getDomainType()
{
return null; //从不调用
}

@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();
}
}


解决方案

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



RF在构建响应时检查在请求/响应期间看到的每个 EntityProxy 以告知客户端当一个实体被删除时(在客户端,它将使用 DELETE c EntityProxyChange em> write operation 。



您当然可以在 isLive >定位器如果可以提供一个更优化的实现。


I'm new to RequestFactory but with generous help of Thomas Broyer and after reviewing documents below it's getting much better :)

But could you please explain why Locator<>.find() is being called so unnecessarily (in my opinion) often ?

In my sample project I have two entities Organization and Person that maintain parent-child relationship. When I fetch Organization Objectify automatically fetches child Person. Also I created two methods in my service layer findOrganizationById and saveOrganization that load and persist objects.

Now consider two scenarios:

When I call findOrganizationById in the client following calls occur on server side:

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)))

By calling OrderDao.findOrganizationById I've already received full graph of objects. Why call .find twice in addition to that? It's extra load on Datastore that cost me money. Of course I cache it but it would be neat to fix it. How can I avoid these additional calls ?

Similar thing happens when I save object(s) by calling saveOrganization in the client. Following calls occur on server side:

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)))

I can understand need for fetching two objects from DataStore before updating it. RequestFactory sends deltas to the server so it needs to have entire object before persisting it. Still since I load full graph at once it would be nice not to have second call which is PojoLocator.find(Key<?>(Organization(1)/Person(2))). And I truly can't understand need for .find() calls after persisting.

Thoughts ?

My proxies

@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);
}

My service

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();
}

and finally my Locator<>

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();
    }
}

解决方案

The pairs of getId and find at the end are the default implementation of Locator#isLive: it assumes an object is live (i.e. still exists in the data store) if finding it by its ID returns a non-null value.

RF checks each EntityProxy it ever seen during the request/response for their liveness when constructing the response, to tell the client when an entity has been deleted (on the client side, it'd then fire an EntityProxyChange event with a DELETE write operation.

You can of course override isLive in your Locator with a more optimized implementation if you can provide one.

这篇关于RequestFactory理论:为什么定位器&f?.find()经常被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆