使用 JPA 在 GAE 中保存许多实体
Posted
技术标签:
【中文标题】使用 JPA 在 GAE 中保存许多实体【英文标题】:Saving many entities in GAE with JPA 【发布时间】:2011-05-14 03:25:29 【问题描述】:我将 JPA 与 Google App Engine 结合使用。 假设我有一个非常简单的@Entity,由一个键和一个字符串组成,仅此而已。我现在创建了 10000 个这些实体,将它们放在一个列表中,现在想要存储所有这些实体。
如果我尝试使用 EntityManager em 和 for 循环来遍历我所有实体的 List...
for(MyEntity entity : listOfAllEntities)
em.persist(entity);
.. 我会得到一个 IllegalArgumentException:
java.lang.IllegalArgumentException:不能在单个事务中对多个实体组进行操作。
据我了解,我需要为每个 persist() 调用关闭并重新打开 EntityManager。当然,这是非常耗时的。 我正在尝试每天运行一次重新加载所有实体的任务。根据 GAE 策略,该任务的超时时间为 30 秒。
因此,另一种方法是一次只保存 500 个实体并多次运行该任务,我认为这比它必须的要复杂。
这是实现我想要做的事情的唯一方法还是我在这里遗漏了什么?
解决方案: 所有的答案都指向同一个方向。我只是通过创建“虚拟父”实体来创建一对多关系。在我的情况下,我真的不需要父母,可以这么说在现实世界中没有多大意义。但是在将这个虚拟实体设置为每个子实体的父实体之后,我可以像以前一样保存它们,而无需过多关心事务。谢谢大家。
【问题讨论】:
Read the answer to this similar question。听起来与您遇到的问题相同。 是的,那是我的问题。我通过添加一个父实体然后拥有一个拥有的一对多关系来修复它,因此它们位于同一个实体组中。 感谢您的链接。不确定我是否可以在我的案例中应用选择的答案,但我会看看它。 哇,这太奇怪了。很好的问答。 @socken23 对不起,我遇到了同样的错误。你能展示一些代码sn-p如何做到这一点吗?我试图更新从 1 个父类扩展的实体列表,但仍然出错。 【参考方案1】:此错误表示您使用事务并尝试对多个实体组进行操作。
来自文档:
事务中的所有数据存储操作必须对同一实体组中的实体进行操作。这包括按祖先查询实体、按键检索实体、更新实体和删除实体。请注意,每个根实体都属于一个单独的实体组,因此单个事务不能创建或操作多个根实体。
您不能只在事务中创建多个根(没有父)实体,但如果每个实体都是另一个实体的子实体,则可以这样做。如果您只想创建实体 - 在事务之外进行。
【讨论】:
这是一个很好的观点。这取决于@socken23 是否真的需要它是事务性的。如果没有,那么不使用您建议的交易就可以了。 谢谢,现在说得通了。我将尝试将它们保存在交易之外。我想我确实有一些阅读要做。我还没有阅读很多关于该主题的内容,并且必须这样做才能查看 GAE 在何处自动使用事务。【参考方案2】:也许这过于简单了,但您可以将 X 个实体添加为父实体的子实体,这会导致它们位于同一个实体组中。这将允许您将它们全部保存在一个事务中。基本上,在父实体和子实体之间创建一个拥有的一对多关系,这些子实体是您试图持久化的对象。
【讨论】:
很有趣,所以我基本上可以为我的所有实体创建一个“虚拟”父级并像我现在尝试的那样保存它们?也试试,谢谢。 是的,没错。具有共同父母的孩子将在同一个实体组中。 如果您不需要事务,请不要将很多实体放在同一个实体组中。这会使您的应用变得非常缓慢。 彼得说得很好。这取决于你是否真的需要交易。以上是关于使用 JPA 在 GAE 中保存许多实体的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security + JPA - 使用许多业务模型(实体)进行用户身份验证