【问题标题】:Why do I get "Persistence Manager has been closed" exception [closed]为什么我会收到“Persistence Manager 已关闭”异常 [关闭]
【发布时间】:2012-12-24 01:15:58
【问题描述】:

我的应用程序的各个部分偶尔会抛出以下异常

Javax.jdo.JDOFatalUserException: Persistence Manager has been closed
    at org.datanucleus.jdo.JDOPersistenceManager.assertIsOpen(JDOPersistenceManager.java:2125)
    at org.datanucleus.jdo.JDOPersistenceManager.newQuery(JDOPersistenceManager.java:1247)
    at org.datanucleus.jdo.JDOPersistenceManager.newQuery(JDOPersistenceManager.java:1198)
    at org.datanucleus.jdo.JDOPersistenceManager.newQuery(JDOPersistenceManager.java:1352)
    at vik.sakshum.sakshumweb.server.LoginModuleServiceImpl.recoverPassword(LoginModuleServiceImpl.java:377)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_$1.run(Method_.java:165)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.privilegedInvoke(Method_.java:163)
    at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke_(Method_.java:124)
    at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke(Method_.java:43)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:561)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:208)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
    at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    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:102)
    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.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:447)
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:454)
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:461)
    at com.google.tracing.TraceContext.runInContext(TraceContext.java:703)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:338)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:330)
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:458)
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251)
    at java.lang.Thread.run(Thread.java:679)

这样的一段代码就在这里

public class AdminDashBoardServiceImpl extends RemoteServiceServlet
implements AdminDashBoardService{   
private static final Logger log =
Logger.getLogger(AdminDashBoardServiceImpl.class.getName());

private PersistenceManager pm;

private static final long serialVersionUID = 1L;

@Override
public List<NotificationBean> pullNotifications() throws Exception {
    log.info("start of pullNotifications");
     Long userId = getUserId();
    try{ 
         pm = PMF.get().getPersistenceManager();
         log.info("Logged in user is:" + userId);

         Query query = pm.newQuery(NotificationRecepient.class, "userId == :userId");
         @SuppressWarnings("unchecked")
         List<NotificationRecepient> notifyList = (List<NotificationRecepient>)query.execute(userId);
         if(notifyList.size() == 0)
             return null;

         //find associated notifications
         List<NotificationBean> nList = new ArrayList<NotificationBean>();
         for(NotificationRecepient notify: notifyList){
                Notification nData = pm.getObjectById(Notification.class, notify.getNotificationSeq());
                NotificationBean bean = new NotificationBean(nData.getNotificationSeq(), nData.getTitle(), nData.getDetail(),
                        nData.getCreationDate(), nData.isClosable());

                //#41769745 add notification in the right order
                boolean inserted = false;
                for(int i=0; i < nList.size(); i++){
                    if(bean.getCreationDate() != null && nList.get(i).getCreationDate() != null )
                    if(bean.getCreationDate().before(nList.get(i).getCreationDate())){
                        nList.add(bean);
                        inserted = true;
                        break;
                    }
                }

                if(inserted == false)
                    nList.add(bean);
             }  

         return nList;

    }catch(Exception e) {
        CommonServiceCode csc = new CommonServiceCode();
        csc.postToPivotalTracker("Error while pulling notifications", "User Data: userId:" + userId, e);

        log.severe("Exception in execute of pullNotifications");
        log.severe("Exception class is :" + 
                             e.getClass().getName());
        log.severe("Exception is :" + e.getMessage());
        e.printStackTrace();

        throw new Exception(e.getMessage() + "\nError while pulling notifications");

      } finally {
          try {
              if(pm != null && pm.isClosed() == false)
                  pm.close();
          } catch (Exception e) {
              log.severe("Exception in finally of execute of pullNotifications");
              log.severe("Exception class is :" + 
                                 e.getClass().getName());
              log.severe("Exception is :" + e.getMessage());
              throw new Exception(e.getMessage() + "Unable to close persistence manager");
          }
           log.info("end of pullNotifications");
      }
}

}

【问题讨论】:

  • 我不知道您的最后一行如何执行。 Admin admin = adminList.get(0); 行应该以 IndexOutOfBoundsException 失败,因为这里列表的大小始终为零。
  • 我很抱歉只是提供一个简短版本的相关代码我犯了错误。刚刚修复了代码
  • 您没有任何代码可以在某处关闭持久性管理器吗?
  • 是的,我有。每个 RPC 服务调用的典型结构 try{ pm = PMF.get().getPersistenceManager(); }catch(Exception e) { log.severe("Exception"); } 最后 { 尝试 { if(pm != null && pm.isClosed() == false) pm.close(); } catch (Exception e) { throw new Exception(e.getMessage() + "Unable to close persistence manager"); } }
  • 在我看来,您刚刚输入了一个代码片段(因为您犯了一个印刷错误)。您为什么不直接复制并粘贴足够大的实际代码片段,让我们看看您在做什么。例如:足以看到您在哪里定义pm 并关闭它。据我们所知,您之前已经关闭了pm,然后再尝试使用它。

标签: java google-app-engine jdo


【解决方案1】:

我有两个建议,尽管可能无法解决您的问题,但可能会间接帮助您。

  1. 不要将pm 声明为类级数据成员。你有需要这样做吗?我从来没有做。如果可以,请根据需要在方法中声明您的 pm。一旦你关闭它,它就可以被丢弃(并且可能会最大限度地减少你获得异常的机会)。

  2. 简化您的pm.close() 代码。如果你不使用事务,为什么不尝试这样的事情:

    PersistenceManager pm = PMF.get().getPersistenceManager();
    try
    {
      //
      // Do your query stuff...
      //
    }
    catch(Exception e)
    {
      //
      // Your code...
      //
    }
    finally
    {
      pm.close();
    }
    

【讨论】:

  • 我会按照你的建议去做,看看它是如何为它进行应用范围内的更改的。
猜你喜欢
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
  • 2011-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多