2

我有一个典型的人地址实体关系。在查询数据存储中的 Person 之后,我会查询 Person 的地址键。键(即addrKey,见下文)始终返回为 null。但是我查看数据存储区,我看到了 Person 和 Address 实体,以及它们的键。很明显,这条线Key addrKey = (Key) person.getProperty("address")没有做我认为应该做的事情。任何想法如何解决这一问题?

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    Map<Key, Entity> entities = datastore.get(keys);

    List<Person> result = new ArrayList<Person>();
    Iterator<Entry<Key, Entity>> it = entities.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<Key, Entity> ent = it.next();

        final Entity person = ent.getValue();
        Key key = person.getKey();
        name = (Long) person.getProperty("name");
        Address address = getAddress(datastore, person);

...
    }


private Address getAddress(DatastoreService datastore, Entity person) {
    Key addrKey = (Key) person.getProperty("address");
    try {
        Entity d = datastore.get(addrKey);
        String street = (String) d.getProperty("street");
…
}
4

1 回答 1

0

我的猜测是您同时保留了地址和人员。但是,默认情况下,地址在被持久化之前具有不完整的键(假设您依赖于键的自动 id 生成)。因此,您亲自存储了不完整的密钥。并且使用不完整的键获取将不起作用。

我写了一个快速测试用例:

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;

public class TempTest extends PersistenceTestHelper {

  @Test
  public void testStackOverflow() throws Exception {

    Entity address = new Entity("address", 1);
    address.setProperty("street", "my street");

    Entity person = new Entity("person", 1);
    person.setProperty("addressKey", address.getKey());
    System.out.println(person);

    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    datastore.put(person);
    datastore.put(address);

    Entity personFromDatastore = datastore.get(person.getKey());
    Key addressKey = (Key) personFromDatastore.getProperty("addressKey");
    Entity addressFromDatastore = datastore.get(addressKey);
    System.out.println("fetched street: " + addressFromDatastore.getProperty("street"));

    address = new Entity("address");
    System.out.println("Address with incomplete key: " + address.getKey());
    try {
      addressFromDatastore = datastore.get(address.getKey());
    } catch (IllegalArgumentException e) {
      System.out.println(e);
    }
  }

}

这是输出:

<Entity [person(1)]:
    addressKey = address(1)
>
fetched street: my street
Address with incomplete key: address(no-id-yet)
java.lang.IllegalArgumentException: address(no-id-yet) is incomplete.

如果我错了,很高兴能理解为什么你的例子中有一个 try catch。并且在预置时间和获取时间的人员实体和地址实体的打印输出也会很好。

于 2013-05-02T09:05:34.190 回答