2014-02-25 123 views
0

我有以下代碼:Cron作業無法使用'For'循環?

EntityManager mgr = null; 
try { 
    mgr = getEntityManager(); 
    ZooperTheme2 theme = null; 
    theme = mgr.find(Theme2.class, "1"); 
    theme.setPopularity(7); 
    mgr.persist(theme); 
    for (int c = 1; c < 204; c++) { 
     theme = mgr.find(Theme2.class, "" + c); 
     theme.calculatePopularity(); 
     mgr.persist(theme); 
    } 
} catch (Exception e) { 
} finally { 
    mgr.close(); 
} 

前的 'for' 循環的部分:

theme = mgr.find(Theme2.class, "1"); 
theme.setPopularity(7); 
mgr.persist(theme); 

工作得很好本身。但是,當我加入「for」循環在所有主題的迭代,沒有主題的更新(包括主題爲「1」使用.setPopularity(7)日誌文件顯示以下錯誤:

Uncaught exception from servlet 
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) 
    at com.companionfree.zooperthemeviewer.CronController.doGet(CronController.java:43) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266) 
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
    at org.mortbay.jetty.Server.handle(Server.java:326) 
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) 
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) 
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) 
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) 
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146) 
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446) 
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437) 
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444) 
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300) 
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441) 
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251) 
    at java.lang.Thread.run(Thread.java:724) 
Caused by: java.lang.IllegalArgumentException: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXG 
    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$6.getFutureWithOptionalTimeout(AsyncDatastoreServiceImpl.java:373) 
    at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl$6.aggregate(AsyncDatastoreServiceImpl.java:345) 
    at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl$6.get(AsyncDatastoreServiceImpl.java:316) 
    at com.google.appengine.api.datastore.AsyncDatastoreServiceImpl$6.get(AsyncDatastoreServiceImpl.java:305) 
    at com.google.appengine.api.datastore.FutureHelper$TxnAwareFuture.get(FutureHelper.java:171) 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:86) 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:86) 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:86) 
    at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:71) 
    at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:58) 
    at com.google.appengine.api.datastore.DatastoreServiceImpl.get(DatastoreServiceImpl.java:51) 
    at com.google.appengine.datanucleus.WrappedDatastoreService.get(WrappedDatastoreService.java:70) 
    at com.google.appengine.datanucleus.EntityUtils.getEntityFromDatastore(EntityUtils.java:667) 
    at com.google.appengine.datanucleus.DatastorePersistenceHandler.updateObject(DatastorePersistenceHandler.java:415) 
    at org.datanucleus.state.JDOStateManager.flush(JDOStateManager.java:3841) 
    at org.datanucleus.ObjectManagerImpl.flushInternalWithOrdering(ObjectManagerImpl.java:3888) 
    at org.datanucleus.ObjectManagerImpl.flushInternal(ObjectManagerImpl.java:3811) 
    at org.datanucleus.ObjectManagerImpl.flush(ObjectManagerImpl.java:3751) 
    at org.datanucleus.ObjectManagerImpl.preCommit(ObjectManagerImpl.java:4141) 
    at org.datanucleus.ObjectManagerImpl.transactionPreCommit(ObjectManagerImpl.java:428) 
    at org.datanucleus.TransactionImpl.internalPreCommit(TransactionImpl.java:398) 
    at org.datanucleus.TransactionImpl.commit(TransactionImpl.java:287) 
    at org.datanucleus.ObjectManagerImpl.close(ObjectManagerImpl.java:1090) 
    at org.datanucleus.api.jpa.JPAEntityManager.close(JPAEntityManager.java:193) 
    ... 35 more 

CronController.java:43是行: mgr.close()

它出現時我添加了對於循環,但我不知道爲什麼我的代碼失敗......

+0

你 「的PersistenceException」。問題不在於循環!它看起來你的代碼在事務中運行,我猜在這個事務中也會更新其他實體。 – MatejC

+0

我知道@MatejC,但問題仍然存在,並且只要添加了For循環就會發生。 – easycheese

回答

0

Developer Guide

「該應用程序使用工廠實例爲每個訪問數據存儲的請求創建一個EntityManager實例「。

我被告知,EntityManager只能調用persist once和error out,如果您嘗試在多個對象上使用它。我的新代碼是:

EntityManager mgr = null; Theme2 theme = null;

for (int c = 1;c<204;c++) { 

     try { 
      mgr = getEntityManager();   
      theme = mgr.find(Theme2.class, "" + c); 
      theme.calculatePopularity(); 

      mgr.persist(theme); 


     } catch (Exception e) { 

     } finally { 
      mgr.close(); 
     } 

    } 

而且它完美的作品:)