Теория RequestFactory: почему Locator <>. Find () вызывается так часто? - PullRequest
8 голосов
/ 28 февраля 2012

Я новичок в RequestFactory, но с щедрой помощью Томас Бройер и после просмотра документов ниже становится намного лучше:)

Но не могли бы вы объяснить, почему Locator<>.find() так часто (на мой взгляд) называют так неоправданно?

В моем примере проекта у меня есть две сущности: Организация и Персона, которые поддерживают отношения между родителями и детьми. Когда я выбираю организацию, Objectify автоматически выбирает ребенка Person. Также я создал два метода в своем слое обслуживания findOrganizationById и saveOrganization, которые загружают и сохраняют объекты.

Теперь рассмотрим два сценария:

Когда я звоню 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)))

Я могу понять необходимость извлечения двух объектов из хранилища данных до его обновления. 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<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();
    }
}

1 Ответ

6 голосов
/ 01 марта 2012

Пары getId и find в конце являются реализацией по умолчанию Locator#isLive: предполагается, что объект live (т.е. все еще существует в хранилище данных), если его найтиего идентификатор возвращает ненулевое значение.

RF проверяет каждый EntityProxy, который он когда-либо видел во время запроса / ответа, на их живучесть при построении ответа, чтобы сообщить клиенту, когда объектбыл удален (на стороне клиента он затем запустит событие EntityProxyChange с DELETE операцией записи .

Вы, конечно, можете переопределить isLive в вашем Locator с более оптимизированной реализацией, если вы можете ее предоставить.

...