Java AppEngine如何计算事务的实体组?

Java AppEngine如何计算事务的实体组?,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,如果我有以下一组实体: A --> (unowned) B \ --> (owned) List<C> D --> (owned) List<E> --> (owned) List<F> --> (unowned) A \ --> (unowned) H G --> (unowned) H \ --> (unowned) D \ --> (unowned) B

如果我有以下一组实体:

A --> (unowned) B
  \
   --> (owned) List<C>

D --> (owned) List<E> --> (owned) List<F> --> (unowned) A
  \
   --> (unowned) H

G --> (unowned) H
  \
   --> (unowned) D
  \
   --> (unowned) B
  \
   --> (unowned) A
  \
   --> (unowned) F
  \
   --> (unowned) F
尽管它是父/子关系,但以某种方式使用两个单独的实体组?或者G有两个不同的F值,是两个实体组还是一个实体组

2) 当你访问一个对象时,它会有多深?i、 如果我也有

D --> (owned) List<K> --> (owned) List<L> --> (unowned) M
D-->(拥有)列表-->(拥有)列表-->(未拥有)M
appengine是否将M包括在事务中访问的实体组列表中,即使我没有访问K、L或M

从概念的角度来看,我对我的对象模型相当满意(如果没有appengine,我很确定我会再次以同样的方式进行设计),但我是否应该像其他人在这里建议的那样,创建一个GenericObject,它以某种方式是所有事物的父对象

或者,考虑到这在数据库世界中非常微不足道,有多少人在6个月内放弃了数据存储以使用云SQL?(也许最后一个对于stackoverflow来说过于主观,但这是一个真实的问题)

更新

在浏览了通过将所有内容打开以进行调试而生成的日志之后,我可以看到,在某个时刻,我得到了以下行:

24634[1419746043@qtp-647750325-2]调试DataNucleus.Persistence-对id为“com.google.appengine.api.datastore.Key:D”的对象执行可达性算法alex@hotmail.com“”“

然后,从根实体开始,对每个可以访问的对象进行大量检索。由于这包括一组无主的实体(即,它们不使用任何作为其父实体访问的实体),我想这就是导致我的事务失败的原因,第二季度的答案似乎是“无处不在”

那么…第三个问题-我如何防止这种行为。请注意,我调用makePersistent(D)是为了持久化已修改的两个F实例。

一些注意事项:

  • 所有高级数据存储API(JDA/JPA/Objectify)都是基于此构建的。它们不能比低级API做得更多。如果您想了解数据存储,您应该了解低级API

  • 实体之间的关系基于一个实体具有另一个实体的键的属性。简单地说:实体包含另一个实体的ID

  • 只需从实体中删除键属性,即可断开实体关系。并没有在SQL world中使用的引用完整性:您可以删除关系任意一侧的实体,而不受任何约束

  • 实体组基于祖先关系,与第2点中提到的实体关系无关。祖先关系基于键:子键将包含所有父键的键

  • 因为祖先关系是基于键的,所以它只能在创建实体时建立。它不能在以后更改,因为键是不可变的

  • 实体组的写入/更新限制为1次写入/秒。因此,将所有实体放在一个通用的GenericObject下确实是个坏主意。您在设计实体组时应该非常小心,因为它们会影响性能。好的起点是将每个用户实体作为实体组的根

  • 实体组设计用于定义事务范围(基本上这意味着这些实体驻留在同一服务器上,因此存在写入限制),您不应该使用它们来建立实体之间的逻辑关系


  • 通过向jdoconfig.xml添加以下内容,我成功地解决了这个问题:

    <property name="datanucleus.persistenceByReachabilityAtCommit" value="false"/>
    
    
    
    这记录在


    如果有人想给我留言,说明为什么需要这样做,或者为什么我的对象模型是错误的,我将非常感激,因为我对JDO和appengine还不熟悉。

    要么我对您的图表感到困惑,要么您还在弄清楚数据存储。
    A-->(无主)B
    是什么意思?所有实体要么有父实体,要么没有父实体。具有相同[direct]父级的实体不能具有相同的密钥。因此,我不确定如何让
    A-->(拥有)列表
    G-->(无主)F
    两次。A-->(无主)B表示A有一个类型为B的字段,该字段用@unowned注释。A不是B的父级,B以前是在单独的事务中创建的。在一个事务中,我做
    aaa=新的a(b,f)(已拥有)列表,那么它的定义完全符合,同样地,1-1和未拥有的1-1关系
    
    <property name="datanucleus.persistenceByReachabilityAtCommit" value="false"/>