2012-02-28 13 views
8

Soy nuevo en RequestFactory pero con generosa ayuda de Thomas Broyer y después de la revisión de documentos abajo se está poniendo mucho mejor :)Teoría de RequestFactory: ¿Por qué se llama tan frecuentemente Locator <>. Find()?

Pero ¿podría por favor explique por qué Locator<>.find() se llama tan innecesariamente (en mi opinión) a menudo?

En mi proyecto de ejemplo, tengo dos entidades Organización y Persona que mantienen la relación padre-hijo. Cuando obtengo Organization Objectify automáticamente obtiene Person. También creé dos métodos en mi capa de servicio findOrganizationById y saveOrganization que cargan y persisten objetos.

Ahora consideran dos escenarios:

Cuando llamo findOrganizationById en el cliente siguiendo las llamadas se producen en el lado del servidor:

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

Llamando OrderDao.findOrganizationById ya he recibido gráfico completo de los objetos. ¿Por qué llamar al .find dos veces además de eso? Es una carga extra en Datastore que me costó dinero. Por supuesto que lo guardo en caché, pero sería bueno arreglarlo. ¿Cómo puedo evitar estas llamadas adicionales?

Algo similar ocurre cuando guardo objeto (s) llamando al saveOrganization en el cliente. Siguientes llamadas se producen en el lado del servidor:

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

que puede entender la necesidad de ir a buscar dos objetos de almacén de datos antes de actualizarlo. RequestFactory envía deltas al servidor por lo que necesita tener un objeto completo antes de persistir. Aún así, dado que cargué el gráfico completo a la vez, sería bueno no tener una segunda llamada que es PojoLocator.find(Key<?>(Organization(1)/Person(2))). Y realmente no puedo entender la necesidad de .find() llamadas después de persistentes.

¿Pensamientos?

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

Mi servicio

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

y finalmente mi localizador <>

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

Respuesta

6

Los pares de getId y find al final son la implementación predeterminada de Locator#isLive : eso asume que un objeto es en vivo (es decir todavía existe en el almacén de datos) si al encontrarlo por su ID se devuelve un valor no nulo.

cheques RF cada EntityProxy se haya visto durante la petición/respuesta para su liveness cuando se construye la respuesta, para decirle al cliente cuando se ha eliminado una entidad (en el lado del cliente, entonces se despediría un evento EntityProxyChange con una operación de DELETEescritura.

por supuesto, puede anular isLive en su Locator con una aplicación más optimizada si se puede proporcionar una.

+0

Después anulando 'isLive()' me confirmó que es la respuesta correcta. – expert

Cuestiones relacionadas