【发布时间】:2012-04-03 22:34:59
【问题描述】:
我想在两个具有持久性的类之间建立一个无主关系,同时创建。这种关系必须是无主的,因为我的应用程序不能真正保证我想要保留的两个实例将永远留在同一个实体组中。我的关系是双向的一对多:
// in first class
@Persistent
private Set<Key> instancesOfSecondClass;
// in second class
@Persistent
private Key instanceOfFirstClass;
然后,在一个 servlet doPost() 调用中,我需要为每个这些类保留一个实例。我实际上做了一个很好的方法来维持双方的关系。首先,Key id(我使用...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key id;
... 作为到处的主键)被添加到第一类的 Set 中,然后在第二类的实例上调用一个便利方法来通知此更改并相应地更新一个 Key 属性,比较旧值,空检查和一切。事实上,当实例是新鲜的时,我还没有任何 Key,所以我需要先用 pm.makePersistent() 调用将它们都持久化,然后执行分配并等待 pm.close() 稍后发生。
但是,真正发生的事情非常令人困惑。运行 servlet(其唯一目的是返回这两个实例的序列化 Keys 以供其他地方使用)后,我去查看数据存储查看器并查看:
- 第一类的实例被持久化了(实际上,在我用
Set<Key>在实例上调用pm.makePersistent()的那一刻,我从org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.postInsert(PersistenceCapableMapping.java:1039)向我抛出了一个NullPointerException的问题) - 第二类的实例被持久化(到目前为止一切都很好)
- 第二类的实例具有对第一个实例的
Key引用,是的,耶 - 第一个实例上的密钥集是……等待它……为空
本地数据存储仅显示空白空间,而在线数据存储显示<null>,尽管我的类构造函数(带参数的构造函数)为关系创建了HashSet<T> 的新实例。
使用 Google App Engine for Java 1.6.4,也发生在 1.6.3 中。
花了一整天的时间试图解决这个问题,将交易放在中间,使用两个PersistenceManagers,不同的持久调用顺序,启用跨组交易,没有任何帮助。
一般来说,我很乐意找到一种可行的方法来创建和更新两个独立实体组中的两个实例,它们之间存在无主关系,无论可能存在不一致(我不用那么担心,基于频率可能的更新)。
同时,我发现了另外两个可能的解决方案,但还没有尝试过:1. 不仅创建两个,而且创建四个PersistenceManagers(一个创建第一个实例,第二个创建第二个实例,第三个更新关系的一侧,第四更新关系的第二侧),或者 2. 分离实例并在更新后再次使它们持久化。现在不知道该走哪条路。
【问题讨论】:
-
或者,第三种可能的解决方案,最及时的一个:升级到最前沿的 DataNucleus 插件 2.0?
-
似乎我错了交易不工作,我只是用错了。现在我在更新周围放了很多
txn = pm.currentTransaction();txn.begin();// the update parttxn.commit();(创建第一个实例,创建第二个实例,更新关系-由于使用跨组事务,一个事务就足够了)。早该发现的。无论如何,App Engine 没有报告任何类型的并发问题这一事实让我很担心,并且在一个实际上很简单的问题上困扰了我一整天。如果它只是抛出一些异常之类的...... -
并且该插件的 v2 提供了“真正的”无主关系,而不是在其中放置一个密钥和一组密钥
-
我已经看到了,但在 App Engine 的文档中没有关于它的更多信息。但我想它仍然需要相同的交易方案来执行所需的操作?或者我可以创建两个新实例,建立关系,然后持久化它们吗?
标签: google-app-engine jdo