【问题标题】:JDO(DataNucleus) collection members are not deletedJDO(DataNucleus) 集合成员不被删除
【发布时间】:2012-09-16 12:19:59
【问题描述】:

我正在使用带有 JDO(DataNucleus)的 GAE 1.7.0。 当我持久化具有集合属性的类时,已移除的集合成员不会从数据存储中移除。我从分离的副本中删除集合成员。新成员被正确添加,现有成员没有被删除,导致我的收藏只会增长。

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

    @Persistent(defaultFetchGroup="true", dependentElement="true")
    private List<Child> children = new ArrayList<Child>(0);

}

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

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String id;

    @Persistent
    @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true")
    private String parentId;
    ....
}

...
parent = pm.detachCopy(resultFromQuery);
// parent looks correct in dubugger: all children are fetched (and detached)
....
parent.getChildren().clear();
parent.getChildren().addAll(newChildren);
for (Child child: parent.getChildren())
    child.setParentId(KeyFactory.createKeyString("Parent", parent.getId()));
// parent looks good in the debugger: old children were removed and new ones added
...
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
    pm.currentTransaction().begin();
    pm.makePersistent(parent);
    pm.currentTransaction().commit();
} catch (Exception e) {
} finally {
    if (pm.currentTransaction().isActive())
        pm.currentTransaction().rollback();
    if (!pm.isClosed())
        pm.close();
}
// problem in datastore: new children were created, old ones not removed

我注意到,如果我在事务中执行 query-remove-persist(不分离对象),那么问题就解决了。这是一个不错的临时解决方法,但我仍然想对分离的对象进行更新。

【问题讨论】:

  • 相同问题 DataNucleus artifactId datanucleus-core 3.1.3 和 Google App Engine 1.9.21。

标签: java google-app-engine jdo datanucleus


【解决方案1】:

我不是 JDO 方面的专家,但这里是……

每个Parent 及其相关的Child 实体都在同一个实体组中。因此,您需要在事务中进行数据存储更新,因为给定实体组的更新频率可能不会超过每秒一次。此外,在事务中,增强魔法将起作用:隐藏、添加的 Java 字节码将处理诸如添加和删除子项以及设置字段值之类的事情。

如果您不想这样做,那么一种方法是不在Parent 中存储Child 实体列表;而是存储Child ID 和/或主键的列表。这将导致每个Child 都在自己的实体组中。但即便如此,您也只能每秒更新每个 Parent(列表)一次。

【讨论】:

  • 不确定,但是...如果您应用 JDO 分离模式,您实际上是在事务中执行数据存储更新。您只需在事务开始之前“准备”对分离对象的更新:db.apache.org/jdo/attach_detach.html
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多