开发者

google app engine: problem getting objects from datastore in a task

开发者 https://www.devze.com 2023-01-13 15:30 出处:网络
My application constructs a Parent object in a static factory, along with it\'s predetermined Children, and then starts up tasks to run some computation on the Children, like so:

My application constructs a Parent object in a static factory, along with it's predetermined Children, and then starts up tasks to run some computation on the Children, like so:

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 : resu开发者_C百科lt.getChild()) {
                q.add(url("/task/child").param("key", KeyFactory.keyToString(c.getKey())).method(Method.PUT));
            }
        }
        pm.close();
        return result;
    }

however in the actual task

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"))); //...

It dies trying to find the object:

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)

Any insights? Also, if it matters, the Parent-child relationship is defined by the parent as a field in the child (hence construction with the parent as an arg).


After some plugging around, the following will work to properly retrieve the desired 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);

I'm still a bit mystified coming from the non-DataStore world as to why the type + id is insufficient to fetch what I want. That seems equivalent to knowing table + primary key in SQL land, and the documentation seems to indicate that the key contains all the parent info, such that having it should be sufficient to do a direct pm.getObjectId(Child, KeyFactory./* etc */).


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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消