我正在使用Eclipse通过Google App引擎开发Android。我有3个实体User-> UserDetails-> UserPassword。每个人都通过USER_ID与另一个人建立@OneToOne关系。以下是实体:
@Entity
public class User {
@Id
@Column(name = "USER_ID", allowsNull="false")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key userId;
@Column(name = "USER_NAME", allowsNull="false")
private String userName;
@OneToOne(cascade = CascadeType.ALL,optional=false,orphanRemoval = true)
@JoinColumn(name = "USER_ID")
private UserDetails userDetails;
//getters & setters
}
@Entity(name="USER_DETAILS")
public class UserDetails {
@Id
@Column(name = "USER_ID", allowsNull="false")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key userId;
@Column(name = "USER_FULLNAME", allowsNull="false")
private String userFullname;
@Column(name = "USER_IMAGEURL", allowsNull="false")
private String userImageURL;
@Column(name = "USER_PASSPHRASE", allowsNull="false")
private String userPassPhrase;
@OneToOne(cascade = CascadeType.ALL,optional=false)
@JoinColumn(name = "USER_ID")
private UserPassword userPassword;
//getters & setters
}
@Entity(name = "USER_PASSWORD")
public class UserPassword {
@Id
@Column(name = "USER_ID", allowsNull="false")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key userId;
@Column(name = "USER_PASSWORD", allowsNull="false")
private String userPassword;
//getters & setters
}
我在removeAllUsers()
中有一个Userendpoint.java
方法。该方法假设获取所有用户,通过它们进行迭代并逐个删除用户,userDetails和密码。
public void removeAllUsers() {
log.info("UserEndpoint.removeAllUsers().....");
EntityManager mgr = getEntityManager();
User user = new User();
try {
CollectionResponse<User> allUsers = listUser(null, null);
Collection<User> users = allUsers.getItems();
Iterator<User> itr = users.iterator();
log.info("UserEndpoint.removeAllUsers()....itr.hasNext="+itr.hasNext());
while(itr.hasNext()){
user = itr.next();
user = mgr.find(User.class, user.getUserId());
//mgr.getTransaction().begin();
mgr.remove(user);
//mgr.getTransaction().commit();
log.info("UserEndpoint.removeAllUsers()....User removed");
}
} finally {
mgr.close();
}
log.info("UserEndpoint.removeAllUsers()....End");
}
我的假设是在用户上使用CascadeType.ALL,当我删除User时,它应该删除UserDetails和Password。我也尝试过Transaction(上面注释掉的行)。我收到以下错误:
WARNING: Delete of com.bean.User@15a9289 needs delete of related object at com..bean.User.userDetails but cannot delete it direct since FK is here
Jun 12, 2014 12:04:01 PM com.google.api.server.spi.SystemService invokeServiceMethod
INFO: cause={0}
javax.persistence.PersistenceException: Illegal argument
at org.datanucleus.api.jpa.NucleusJPAHelper.getJPAExceptionForNucleusException(NucleusJPAHelper.java:298)
at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:197)`enter code here`
at com.cloudmobilebanking.bean.UserEndpoint.removeAllUsers(UserEndpoint.java:202)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
在一些行之后我也看到了以下评论:
Caused by: java.lang.IllegalArgumentException: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXGfound both Element {
type: "User"
id: 0x10780000000000
}
and Element {
type: "User"
id: 0x12b80000000000
}
我尝试过使用TransactionOptions但遇到同样的错误。
我也尝试删除密码然后删除userDetails,然后在该seqyence中删除User,但仍然是同样的错误。
我有什么想法可以解决这个问题吗?
答案 0 :(得分:0)
在使用JPA / JDO + google端点工作一段时间后,我放弃了(有多个问题)。 JPA / JDO更适用于RDBMS,但Google数据库更像是HashMap。我决定尝试专为Google数据存储设计的Objectify。我的经验更好。您需要阅读以下解决方案以及GAE+Objectify - Parameterized type com.googlecode.objectify.Ref not supported处的讨论 为了更好地理解。
为了删除Objectify中的User,UserDetails和Password,下面是代码。
@ApiMethod(name =“deleteAllUsers”,path =“delete_all_users”)
public void deletAllUsers(){
log.info("UserEndpoint.deletAllUsers...");
List<User> users = ofy().load().type(User.class).list();
User user = null;
try{
for(int i=0; i< users.size(); i++){
user = users.get(i);
UserDetails userDetails = user.getUserDetails();
UserPassword userPassword = user.getUserPassword();
ofy().delete().entity(userDetails).now();
ofy().delete().entity(userPassword).now();
ofy().delete().entity(user).now();
}
}
catch(Exception e){
log.info("AccountEndpoint.deleteAllUsers()...exception="+e.getMessage());
}
log.info("AccountEndpoint.deletAllUsers...all users deleted");
}