Java jpa IllegalArgumentException异常

Java jpa IllegalArgumentException异常,java,google-app-engine,jpa,Java,Google App Engine,Jpa,我的项目中有三个实体类 public class Blobx { @ManyToOne private Userx user; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Key id; } public class Index { @Id private String keyword; @OneToMany(cascade = CascadeType.PERSIST) private List<Blo

我的项目中有三个实体类

public class Blobx {
@ManyToOne
private Userx user;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
}

public class Index  {
@Id
private String keyword;
@OneToMany(cascade = CascadeType.PERSIST)
private List<Blobx> blobs;
}

public class Userx  {
@Id
private String name;  
@OneToMany(mappedBy = "user")
private List<Blobx>blobs;
}
作为

我不明白出了什么问题?

发生的事情(基于错误消息)是,您试图在一个事务中持久化
索引,该索引包含
Blobx
es,其中包含
Userx
es,它们都位于不同的实体组中。当您调用
em.persist(index)
时,它将级联持久化其中的所有实体以及其中的所有实体

将实体组视为计算机集群。您的一些
索引
e位于内华达州的集群A上。其中包含的
Blobx
es位于缅因州的集群B上,而包含的
Userx
es位于德克萨斯州和俄勒冈州的集群B和C上。它们是如何在那里结束的完全是随机的,并且(就您的代码而言)完全不受您的控制。要求App Engine持久化所有这些地理位置不同的实体,并知道其中一个实体何时失败(即在交易中),这几乎是不可能的,并且需要大量的网络串扰才能让所有各方都知道所有其他各方都在做得很好。所以这是不允许的

你要做的是确保谷歌将你所有的实体放在一个实体组中,这意味着它们都在一个(地理)地方。要做到这一点,请阅读,其中描述了如何确保您的实体最终位于同一实体组中,这意味着它们将能够在所有实体上进行事务处理

现在,实体分组有它的缺点。即数据存储的缓慢和不均衡利用(例如,现在您的所有实体都将位于德克萨斯州,俄勒冈州的用户将看到不必要的缓慢!),因此只有在您绝对需要在所有实体上使用事务时才使用实体组。例如,除非必须使用级联持久化,否则不要使用级联持久化,或者除非必须使用,否则不要在事务中使用级联持久化

    em.getTransaction().begin();
    em.persist(index);
    em.getTransaction().commit();//exception is thrown
    em.close();
Caused by: java.lang.IllegalArgumentException: can't operate on multiple entity groups in a single transaction. found both Element 


{
    type: "Index"
   name: "function"
  }
  and Element {
    type: "Userx"
    name: "18580476422013912411"
  }