问题
Is there a way to ensure the same PersistenceManager instance is used throughout the different code parts executed in the context of the same RPC request?
Having to manually handle out the persistence manager instance from function to function is quite a pain:
for example:
private void updateItem(ItemModel listItem)
throws UserNotLoggedInException {
PersistenceManager pm = PMF.get().getPersistenceManager();
if (isItemIsNew(pm, listItem)) {
workOnItem(pm, listItem);
}
workSomeMoreOnItem(pm, listItem);
}
回答1:
Google Cookbook offers the following answer:
Using a filter, you can make the PersistenceManager available and guarantee that it is closed at the end of the request. If you are using an MVC framework that handles the rendering for you such as Spring, then this is also useful to keep the manager open long enough for the View to still be able to fetch persistent objects that haven't already been accessed.
public final class PersistenceFilter implements Filter {
private static final PersistenceManagerFactory persistenceManagerFactory
= JDOHelper.getPersistenceManagerFactory("transactions-optional");
private static PersistenceManagerFactory factory() {
return persistenceManagerFactory;
}
private static ThreadLocal currentManager = new ThreadLocal();
public static PersistenceManager getManager() {
if (currentManager.get() == null) {
currentManager.set(factory().getPersistenceManager());
}
return currentManager.get();
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
PersistenceManager manager = null;
try {
manager = getManager();
//Optional: allow all persistent objects implementing a custom interface
//to be notified of when they are saved and loaded.
manager.addInstanceLifecycleListener(new PersistHookListener(), PersistHooks.class);
chain.doFilter(req, res);
} finally {
if (manager != null) {
manager.flush();
manager.close();
}
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {}
@Override
public void destroy() {}
}
http://appengine-cookbook.appspot.com/recipe/persistencefilter/?id=ahJhcHBlbmdpbmUtY29va2Jvb2tyigELEgtSZWNpcGVJbmRleCI2YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUVnc1NDRU5oZEdWbmIzSjVJZ1JLWVhaaERBDAsSBlJlY2lwZSI3YWhKaGNIQmxibWRwYm1VdFkyOXZhMkp2YjJ0eUVnc1NDRU5oZEdWbmIzSjVJZ1JLWVhaaERBMAw
来源:https://stackoverflow.com/questions/2021287/how-to-always-use-the-same-persistencemanager-within-the-same-rpc-request-on-goo