Reputation: 8411
i've three entity classes in my project
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;
}
while running the following lines app engine throws an exception
em.getTransaction().begin();
em.persist(index);
em.getTransaction().commit();//exception is thrown
em.close();
as
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"
}
i can't understand what's wrong?
Upvotes: 0
Views: 742
Reputation: 20930
What's happening (based on the error message) is that you're trying to persist the Index
, which contains Blobx
es, which contain Userx
es, which are all in different entity groups, in a transaction. When you call em.persist(index)
, it will cascade persist all the entities inside it, and all those inside them.
Think of an entity group as a cluster of machines. Some of your Index
es are on Cluster A, in Nevada. The Blobx
es contained within are on Cluster B, in Maine, and the Userx
es contained in there are in Clusters B and C, in Texas and Oregon. How they all ended up there is entirely random, and (with your code as it is) entirely out of your control. Asking App Engine to persist all of these geographically disparate entities and know when one fails (i.e., in a transaction) is nearly impossible, and would require a ton of network cross-talk to have all parties know that all other parties are doing okay. So it's not allowed.
What you want to do is make sure Google puts all your entities in one Entity Group, which will mean that they're all in one (geographical) place. To do that, read the docs for Transactions, which describe how to make sure your entities end up in the same entity group, which means they'll be able to have a transaction worked on all of them.
Now, entity-grouping things has its downsides. Namely slowness, and uneven utilization of the datastore (e.g., now that all your entities will be in Texas, users in Oregon will see unnecessary slowness!), so only use entity groups if you absolutely need to use transactions on all entities. For example, don't use a cascading persist unless you actually have to, or don't do it in a transaction unless you actually have to.
Upvotes: 1