Google App Engine: проблема с получением объектов из хранилища данных в задаче - PullRequest
3 голосов
/ 25 августа 2010

Мое приложение создает объект Parent в статической фабрике вместе с его заранее определенным Child реном, а затем запускает задачи для выполнения вычислений на Child рене, например:

public static Parent make(User owner, List<Integer> data, int size) {
        Parent result = new Parent(owner,data,size);
        PersistenceManager pm = PersistenceSource.get();
        Transaction tx = pm.currentTransaction();

        try {
            tx.begin();
            result = pm.makePersistent(result);
            for (int i=0; i<size; pm.makePersistent(new Child(result,i++)));
            pm.close();
            tx.commit();
        } finally {
            if (tx.isActive()) { tx.rollback(); result=null; }
        }

        if (result!=null) {
            Queue q = QueueFactory.getDefaultQueue();
            for (Child c : result.getChild()) {
                q.add(url("/task/child").param("key", KeyFactory.keyToString(c.getKey())).method(Method.PUT));
            }
        }
        pm.close();
        return result;
    }

однако в реальном задании

public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    PersistenceManager pm = PersistenceSource.get();

    Child c = pm.getObjectById(Child.class, KeyFactory.stringToKey(request.getParameter("key"))); //...

Он умирает, пытаясь найти объект:

Could not retrieve entity of kind Child with key Child(24)
org.datanucleus.exceptions.NucleusObjectNotFoundException: Could not retrieve entity of kind Child with key Child(24)

Есть идеи?Кроме того, если это имеет значение, отношение «родитель-потомок» определяется родителем как поле в дочернем элементе (следовательно, конструкция с родителем в виде аргумента).

Ответы [ 2 ]

3 голосов
/ 25 августа 2010

После некоторого подключения, следующее будет работать для правильного получения желаемого Child:

    Key k = new KeyFactory
        .Builder(Parent.class.getSimpleName(), Long.valueOf(request.getParameter("parent")))
        .addChild(Child.class.getSimpleName(), Long.valueOf(request.getParameter("child")))
        .getKey();
    Child c = pm.getObjectById(Child.class, k);

Я все еще немного озадачен, приходя из мира, не являющегося DataStore, относительно того, почему тип +Идентификатора недостаточно, чтобы получить то, что я хочу.Это похоже на знание таблицы + первичный ключ в земле SQL, и документация указывает на то, что ключ содержит всю родительскую информацию, так что наличия этого должно быть достаточно для прямого pm.getObjectId(Child, KeyFactory./* etc */).

0 голосов
/ 15 марта 2013
public Object retrieveChildByKey(Key parent, Class childClass, int idChild){
    try{
        pm = PMF.get().getPersistenceManager();
        Key objectKey = KeyFactory.createKey(parent, childClass.getSimpleName(), idChild);
        Object result = pm.getObjectById(childClass, objectKey);
        return result;
    }
    catch (DatastoreTimeoutException ex) {
        // Display a timeout-specific error page
        message = "Timeout: An error has occurred: Was not possible to retrieve the Object";
        System.out.println(message);
        ex.printStackTrace();
    }
    catch(Exception ex){
        message = "Timeout: An error has occurred: Was not possible to retrieve the Object";
        System.out.println(message);
        ex.printStackTrace();
    }finally{
        pm.close();
    }
    return null;
}
...