【问题标题】:JPA delete all not working on Google app engineJPA删除所有不适用于Google应用引擎
【发布时间】:2014-10-18 18:25:22
【问题描述】:

我有以下代码并试图删除所有类别,但它抛出了非法参数异常。我正在使用谷歌应用引擎。

public void deleteCategories() {
  EntityManager em = EMFService.get().createEntityManager();



  try {

      em.getTransaction().begin();
      Query q = em.createQuery("DELETE FROM Category cat");
      q.executeUpdate();
      em.getTransaction().commit();
      System.out.println("All records are deleted.");
  } catch(Exception ex){
      System.out.println(ex.toString());

  }
  finally {
      if (em.getTransaction().isActive()) {
          em.getTransaction().rollback();
      }
  }
  }

运行此代码后,我得到 javax.persistence.PersistenceException: Illegal argument 完整堆栈跟踪如下 引起:java.lang.IllegalArgumentException:跨组事务需要显式指定,参见TransactionOptions.Builder.withXGfound既Element { 类型:“类别” 名称:“1” } 和元素{ 类型:“类别” 名称:“100223” }

at com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:39)
at com.google.appengine.api.datastore.DatastoreApiHelper$1.convertException(DatastoreApiHelper.java:76)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:94)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl$10.get(AsyncDatastoreServiceImpl.java:622)
at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl$10.get(AsyncDatastoreServiceImpl.java:618)
at com.google.appengine.api.datastore.FutureHelper$TxnAwareFuture.get(FutureHelper.java:171)
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:71)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:32)
at com.google.appengine.api.datastore.DatastoreServiceImpl.delete(DatastoreServiceImpl.java:128)
at com.google.appengine.datanucleus.WrappedDatastoreService.delete(WrappedDatastoreService.java:184)
at com.google.appengine.datanucleus.query.DatastoreQuery.wrapEntityQueryResult(DatastoreQuery.java:417)
at com.google.appengine.datanucleus.query.DatastoreQuery.performExecute(DatastoreQuery.java:343)
at com.google.appengine.datanucleus.query.JPQLQuery.performExecute(JPQLQuery.java:176)
at org.datanucleus.store.query.Query.executeQuery(Query.java:1789)
at org.datanucleus.store.query.Query.executeWithMap(Query.java:1693)
at org.datanucleus.api.jpa.JPAQuery.executeUpdate(JPAQuery.java:124)
... 28 more

【问题讨论】:

  • 我通过在 persitence.xml 中添加 来为 gae 启用 xg 事务,从而克服了这个异常,但现在我也开始操作了单个事务中的多个实体组。我认为这与stackoverflow.com/questions/16675041/… 有关

标签: java google-app-engine jpa


【解决方案1】:
  1. delete 语句中无需使用别名,因此您可以从 JPQL 中删除 cat
  2. 您应该只回滚 catch 块部分中的事务。
  3. 您应该始终在使用后关闭EntityManager,通常在finally 块中。
  4. 您只打印堆栈跟踪的第一行。这是一个不好的做法。相反,在公共输出中打印堆栈跟踪。或者更好的是,使用为您处理日志文件和异常打印的记录器。

代码如下所示

public void deleteCategories() {
    EntityManager em = EMFService.get().createEntityManager();
    try {
        em.getTransaction().begin();
        Query q = em.createQuery("DELETE FROM Category");
        q.executeUpdate();
        em.getTransaction().commit();
        System.out.println("All records are deleted.");
    } catch(Exception ex){
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }
        //should be changed for something like
        //log.error("Error while deleting all the categories", ex);
        ex.printStacktrace(System.out);
    } finally {
        em.close();
    }
}

【讨论】:

  • 感谢 Luiggi,但使用上述方法后,我得到了 SEVERE: javax.persistence.PersistenceException: FROM 查询子句有类 com.myapp.model.Category 但没有别名
【解决方案2】:

cat 在您的查询中做了什么?我猜是这个错误,因为删除行的一般查询模式如下,不需要使用别名:

DELETE * FROM mytablename

从我的表名中删除

也许你可以在这个已经回答的问题中进一步检查 -> Removing all rows from a table using JPA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-20
    • 2012-12-13
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2020-01-09
    相关资源
    最近更新 更多