Why do I get “Persistence Manager has been closed” exception [closed]

只谈情不闲聊 提交于 2019-12-14 03:34:23

问题


My application various pieces occasionaly throw following exception

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)

The one of such piece of code is here

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");
      }
}

}


回答1:


I have two suggestions which, even though may not solve your problem, might help indirectly.

  1. Do not declare pm as a class-level data member. Do you have a need to do this? I never do. If you can, declare your pm inside a method as needed. Once you have closed it, it can be discarded (and might minimise the chance of you getting your exception).

  2. Simplify your pm.close() code. If you do not use transactions, why not try something like this:

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


来源:https://stackoverflow.com/questions/14016052/why-do-i-get-persistence-manager-has-been-closed-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!