检测到无法保存非常简单的实体的cos XG事务集

时间:2014-06-08 21:41:56

标签: java jpa google-cloud-datastore datanucleus

我有以下实体

@Entity
public class Product implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
    @Basic
    private String title;
    @Basic
    private double price;
    @Basic
    private String description;
    private Map<String, Integer> map;
}

然后我尝试用EntityManager

来保留一些这样的对象
EntityManager em = EMF.get().createEntityManager();
for (int i = 0; i < 10; i++) {
      Product p = new Product();
      //call setters
      em.persist(p);
}
em.close();

但是,当电话EM关闭时

java.lang.IllegalArgumentException: operating on too many entity groups in a single transaction.

问题是为什么使用单个实体组(&#39;产品&#39;在我的脑海中)操作这个异常?

感谢。

1 个答案:

答案 0 :(得分:0)

所有Product都不在同一个实体组中。使用JPA,Product将是您的实体 kind 。 JDO&amp; JPA隐藏了底层数据存储区结构,它是分层的,就像您的操作系统目录一样。

将实体组视为数据树,您的根实体就是树根。为了提供一个明确的例子,我将向Product添加一个ProductDetail子实体。假设每个产品都有许多产品细节:

/** Root entity */
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    // ...

    /** Children entities */
    @OneToMany
    private List<ProductDetail> details;

}

@Entity
public class ProductDetail {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;
}

您的数据将转换为以下分层“架构”:

Product(id=1) 
|__ProductDetail(id=2)
|__ProductDetail(id=3)
|__ProductDetail(id=7)

Product(id=4)
|__ProductDetail(id=5)
|__ProductDetail(id=6)
...

如您所见,如果您的Product实体不共享一个共同的父实体(例如,其他一些类持有@OneToMany对产品的引用),则每个实体都被视为根实体,意味着每个产品都在自己的实体组中。

现在docs对实体组的交易说了什么:

(使用JPA,“正常”和XG事务之间的区别由框架处理)

  

事务中的所有数据存储区操作都必须对其中的实体进行操作   如果事务是单个组,则为同一实体组   交易,或者最多五个实体组中的实体   transaction是一个跨组(XG)事务。

这就是为什么在单个数据存储区事务中创建10个新的Product(根)实体无疑会失败。

另一方面,使用上面的示例,如果它们属于同一个ProductDetail实体,您可以在同一个事务中创建20个Product个实体。 (您也可以同时更新产品)