谷歌应用程序引擎:在任务中从数据存储区获取对象时出现问题

发布于 2024-09-16 06:17:12 字数 1606 浏览 4 评论 0原文

我的应用程序在静态工厂中构造一个 Parent 对象及其预定的 Children,然后启动任务以在 Child 上运行一些计算>ren,就像这样:

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)

有什么见解吗?此外,如果重要的话,父子关系由父级定义为子级中的字段(因此以父级作为参数进行构造)。

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 : result.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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

靖瑶 2024-09-23 06:17:12

经过一些插入后,以下内容将可以正确检索所需的 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 世界的我仍然有点困惑,为什么类型 + id 不足以获取我想要的内容想。这似乎相当于在 SQL 领域中了解表 + 主键,并且文档似乎表明该键包含所有父信息,因此拥有它应该足以执行直接 pm.getObjectId(Child, KeyFactory. /* 等 */)

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 */).

我很OK 2024-09-23 06:17:12
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;
}
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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文