如果两个实体的类型都是PersistentLogin,为什么我会收到以下例外?我认为这意味着他们属于同一个实体组,但我猜这是一个不正确的假设。任何想法如何解决这个问题?
这是代码:
// the class is marked with @Transactional
@Override
public final void removeUserTokens(final String username) {
final Query query = entityManager.createQuery(
"SELECT p FROM PersistentLogin p WHERE username = :username");
query.setParameter("username", username);
for (Object token : query.getResultList()) {
entityManager.remove(token);
}
}
这是一个例外:
Caused by: javax.persistence.PersistenceException: Illegal argument
at org.datanucleus.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:260)
at org.datanucleus.jpa.EntityTransactionImpl.commit(EntityTransactionImpl.java:122)
at org.datanucleus.store.appengine.jpa.DatastoreEntityTransactionImpl.commit(DatastoreEntityTransactionImpl.java:50)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467)
... 42 more
Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found both Element {
type: "PersistentLogin"
name: "1WfCYx8bmwUGkjzP2PpmFA=="
}
and Element {
type: "PersistentLogin"
name: "SfI0P8RVBjTvu0WHMSuaVA=="
}
答案 0 :(得分:5)
相同的实体组意味着实体具有共同的父实体。
两个顶级实体永远不会在同一个实体组中。
任何想法如何解决这个问题?
最简单的方法是放宽交易要求。在你的情况下,这将意味着逐个删除PersistentLogin实体(尽力而为循环,尽可能删除,重试错误,不保证原子性)。
如果您想将同一用户的PersistentLogin放在同一个实体组中,您需要对数据模型进行相当大的更改,对整体性能产生不确定的影响。
对于非关系数据库,您必须编写应用程序代码而不依赖于数据存储上的事务。他们只是在我们习惯的程度上不支持他们。
答案 1 :(得分:1)
首先,请仔细阅读以下文档,尤其是“使用跨群组交易”一节 http://code.google.com/appengine/docs/java/datastore/transactions.html
有关跨群组交易的信息: http://code.google.com/appengine/docs/java/datastore/overview.html#Cross_Group_Transactions
注意:您最多可以在5个不同的组中运行交易!
对于生产appengine ,您必须在appengine仪表板中启用“High Replication Datastore”,并且必须在源代码jdoconfig.xml中启用“跨组(XG)事务”或的persistence.xml
对于开发appengine服务器,您必须确保模拟高复制数据存储。这是described here
注意:如果启动appengine dev server命令行,请不要忘记添加高复制数据存储选项:
~/appengine-java-sdk-1.6.2.1/bin/dev_appserver.sh
--jvm_flag=-Ddatastore.default_high_rep_job_policy_unapplied_job_pct=20
--address=0.0.0.0 --port=8888 --disable_update_check .
我们在开发Rogerthat Platform(代码在生产和Eclipse中工作,而不是在dev_appserver.sh执行命令行时)时遇到了一些困难,所以我们认为值得分享。