问题
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.
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 yourpm
inside a method as needed. Once you have closed it, it can be discarded (and might minimise the chance of you getting your exception).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