我的应用程序偶尔抛出以下异常
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");
}
}
}
答案 0 :(得分:3)
我有两条建议,即使可能无法解决您的问题,也可能间接有所帮助。
不要将pm
声明为类级别数据成员。你有这个需要吗?我从来没有做。如果可以,请根据需要在方法内声明pm
。一旦你关闭它,它就可以被丢弃(并且可以最大限度地减少你获得例外的机会)。
简化您的pm.close()
代码。如果您不使用交易,为什么不尝试这样的事情:
PersistenceManager pm = PMF.get().getPersistenceManager();
try
{
//
// Do your query stuff...
//
}
catch(Exception e)
{
//
// Your code...
//
}
finally
{
pm.close();
}