【问题标题】:Updating child objects in Google App Engine using DataNucleus JDO使用 DataNucleus JDO 在 Google App Engine 中更新子对象
【发布时间】:2011-02-13 18:42:47
【问题描述】:

我花了几个小时试图解决这个问题,尽管尝试了几个建议,但我似乎无法让我的子实体更新。我已经广泛地查看了 GAE 文档,并尝试将事物放入事务中,尝试将它们设为“拥有”对象并使其成为“默认获取组”的一部分。运行下面的虚拟“populateDatastore”方法后,这些对象正确地保存在数据存储中,我可以毫无问题地从数据存储中检索它们。当我进行更改时,这些更改不会保留,尽管我使用的是 setter 方法,因此 JDO 会获取更改。我不是 Java 专家,所以我可能正在做一些非常明显错误的事情,我没有看到它。

父对象

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Parent {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent
  private String invitationCode;

  @Persistent(defaultFetchGroup = "true")
  private Child child;

  // additional ivars and getters and setters
}

子对象

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Response {

  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;

  @Persistent(mappedBy = "child")
  private Parent parent;

  // additional ivars and getters and setters
}

我有几种方法可以检索和保存对象。

public void persistParent(Parent p, boolean closeSession){
  manager = PMF.get().getPersistenceManager();
  manager.makePersistent(p);

  if(closeSession) {
    manager.close();
  }
}

public Transaction beginTransaction() {
  int retries = 3;
  manager = PMF.get().getPersistenceManager();
  Transaction tx = manager.currentTransaction();

  try {
    tx.begin();
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    return null;
  }
  catch(Exception e) {
    return null;
  }
  return tx;
}

public boolean endTransaction(Transaction tx) throws Exception {
  int retries = 3;
  try {
    tx.commit();
  }
  catch(ConcurrentModificationException e) {
if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(com.google.apphosting.api.ApiProxy.CapabilityDisabledException e) {
    if (retries == 0) {
      throw e;
    }
--retries;
  }
  catch(Exception e) {
    if (retries == 0) {
      throw e;
    }
    --retries;
  }
  finally {
    if(tx.isActive()) {
      tx.rollback();
    }
  }

  manager.close();

  return true;
}

public List<Parent> getParentWithID(String code, boolean closeSession) {
  Query q = PMF.get().getPersistenceManager().newQuery(Parent.class);
  q.setFilter("code == codeParam");
  q.declareParameters("String invitationCodeParam");

  List<Invitation> results = null;
  try {
    results = (List<Parent>) q.execute(code);
  } 
  finally {
    if(closeSession) {
      q.closeAll();
    }
  }

 return results;
 }

最后,我有一个虚拟方法可以将一些数据放入数据存储区进行测试。我将几个孩子添加到孩子列表中,但为了简洁起见,我已经删除了很多冗余代码。我也持久化了几个父对象。

Child c = new Child(arg1, arg2, arg3);
c.setSomeIVarForChild(arg1);
p = new Parent(arg1, arg2, arg3);
p.getChildList().add(c);
rsvpDao.persistParent(p, true);

【问题讨论】:

    标签: java google-app-engine google-cloud-datastore entity jdo


    【解决方案1】:

    我不知道“PMF.get()”背后的具体实现是什么,但如果您在每个 get() 上创建一个新的 PersistenceManagerFactory - 没有必要,您可以将其作为静态成员。 如果这不是问题,请尝试检查您是否使用相同的 PersistenceManager 来检索和更新数据对象:这意味着只调用一次 PMF.get().getPersistenceManager() em> 用于整个操作。如果您需要查询对象,然后使用不同的 PersistenceManager 将它们持久化,您应该 detach

    【讨论】:

    • PMF 只是 PersistenceManagerFactory 的 Java 单例的 Google 示例。我将它作为静态参考,所以我知道我使用的是同一个参考。有趣的是,如果我想处理实体(使用分离),我必须使用不同的工作流程来获取实体,而不是只希望它用于只读访问并且如上所述标注类是不够的JDO 的线索。
    • 所以现在我在我正在检索的对象上调用“detachCopy()”,我现在得到“ID 为 的对象由不同的对象管理器管理。”我查看了我的代码,每次使用它时都会关闭我的 PM,所以我不认为这是资源泄漏......我不太确定发生了什么。
    • 您可以使用 JDOHelper.getPersistenceManager([your object]) 并查看这是否与您正在执行 pm.detachCopy() 进行调试的 PM 相同。确保在拥有对象但在关闭用于检索它的 PM 之前调用 detachCopy()。
    • 如果不是因为涉及到继承,这实际上是正确的解决方案。我正在阅读 datanucleus 文档,发现不支持继承 + 应用引擎 + 分离。
    • 我和 David 有同样的问题 -> “ID 的对象由不同的对象管理器管理。”关于如何解决这个问题的任何想法?我想我会尝试: if(JDOHelper.getPersistenceManager(obj) != pm) { jobs.add(JDOHelper.getPersistenceManager(obj).detachCopy(obj)); } 其他 { 工作.add(pm.detachCopy(obj)); }
    【解决方案2】:

    我面临的问题是我的父对象主键是“Key”对象。更改为 Long 工作。不知道确切的问题是什么以及它是如何解决问题的,因为我是 android 和 gae 的新手

    【讨论】:

      【解决方案3】:

      我添加了以下内容并解决了我的问题:

      if(JDOHelper.getPersistenceManager(obj) != pm) {
          logger.error("JDOHelper.getPersistenceManager(obj) != pm  ->     JDOHelper.getPersistenceManager(obj)[" +     JDOHelper.getPersistenceManager(obj).toString() + "]"
                                  + " pm[" + pm.toString() + "]");
                          detatchedJob =     JDOHelper.getPersistenceManager(obj).detachCopy(obj);
                          jobs.add(detatchedJob);
                      } else {
                          detatchedJob = pm.detachCopy(obj);
                          jobs.add(detatchedJob);
                      }
      

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 2012-06-14
        • 2011-01-01
        • 2014-01-24
        • 1970-01-01
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 2023-04-03
        相关资源
        最近更新 更多