2012-02-28 26 views
8

Tôi mới đến RequestFactory nhưng với sự giúp đỡ hào phóng của Thomas Broyer và sau khi xem xét các văn bản dưới đây nó trở nên tốt hơn nhiều :)Lý thuyết RequestFactory: Tại sao Locator <>. Find() được gọi quá thường xuyên?

Nhưng có thể bạn vui lòng giải thích tại sao Locator<>.find() đang được gọi một cách không cần thiết (theo ý kiến ​​của tôi) thường xuyên?

Trong dự án mẫu của tôi, tôi có hai thực thể Tổ chức và cá nhân duy trì mối quan hệ cha-con. Khi tôi tìm nạp Tổ chức Objectify tự động tìm nạp Người con. Ngoài ra, tôi đã tạo hai phương thức trong lớp dịch vụ findOrganizationByIdsaveOrganization các đối tượng tải và tồn tại đó.

Bây giờ xem xét hai kịch bản:

Khi tôi gọi findOrganizationById trong các khách hàng các cuộc gọi sau đây xảy ra trên phía máy chủ:

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

Bằng cách gọi OrderDao.findOrganizationById tôi đã nhận được đồ thị đầy đủ các đối tượng. Tại sao lại gọi .find hai lần ngoài điều đó? Đó là tải thêm vào Datastore mà chi phí cho tôi tiền. Tất nhiên tôi nhớ cache nó nhưng nó sẽ được gọn gàng để sửa chữa nó. Làm cách nào để tránh các cuộc gọi bổ sung này?

Điều tương tự cũng xảy ra khi tôi lưu (các) đối tượng bằng cách gọi saveOrganization trong ứng dụng khách. cuộc gọi sau đây xảy ra trên phía máy chủ:

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

Tôi có thể hiểu được nhu cầu lấy hai đối tượng từ DataStore trước cập nhật nó. RequestFactory gửi deltas đến máy chủ để nó cần phải có toàn bộ đối tượng trước khi kiên trì nó. Tuy nhiên kể từ khi tôi tải đầy đủ đồ thị cùng một lúc nó sẽ được tốt đẹp không có cuộc gọi thứ hai là PojoLocator.find(Key<?>(Organization(1)/Person(2))). Và tôi thực sự không thể hiểu được cần .find() gọi sau sự kiên trì.

Suy nghĩ?

proxy My

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

dịch vụ My

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

và cuối cùng Locator tôi <>

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

Trả lời

6

Các cặp getIdfind ở cuối là việc thực hiện mặc định của Locator#isLive : nó giả định một đối tượng là trực tiếp (tức là vẫn tồn tại trong kho dữ liệu) nếu tìm thấy nó bằng ID của nó trả về giá trị không null.

kiểm tra RF mỗi EntityProxy nó từng thấy trong request/response cho liveness khi xây dựng các phản ứng, nói với khách hàng khi một thực thể đã bị xóa (trên các mặt hàng, nó muốn sau đó bắn một sự kiện EntityProxyChange của họ với một hoạt động DELETEghi.

bạn có thể tất nhiên ghi đè isLive trong Locator bằng việc triển khai tối ưu hơn nếu bạn có thể cung cấp một.

+0

Sau trọng 'isLive() 'tôi khẳng định rằng đó là câu trả lời đúng. – expert

Các vấn đề liên quan