@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      // Invocation on PersistenceManager interface coming in...

      if (method.getName().equals("equals")) {
        // Only consider equal when proxies are identical.
        return (proxy == args[0]);
      } else if (method.getName().equals("hashCode")) {
        // Use hashCode of PersistenceManager proxy.
        return System.identityHashCode(proxy);
      } else if (method.getName().equals("toString")) {
        // Deliver toString without touching a target EntityManager.
        return "Spring PersistenceManager proxy for target factory ["
            + getPersistenceManagerFactory()
            + "]";
      } else if (method.getName().equals("getPersistenceManagerFactory")) {
        // Return PersistenceManagerFactory without creating a PersistenceManager.
        return getPersistenceManagerFactory();
      } else if (method.getName().equals("isClosed")) {
        // Proxy is always usable.
        return false;
      } else if (method.getName().equals("close")) {
        // Suppress close method.
        return null;
      }

      // Invoke method on target PersistenceManager.
      PersistenceManager pm =
          PersistenceManagerFactoryUtils.doGetPersistenceManager(
              getPersistenceManagerFactory(), isAllowCreate());
      try {
        Object retVal = method.invoke(pm, args);
        if (retVal instanceof Query) {
          PersistenceManagerFactoryUtils.applyTransactionTimeout(
              (Query) retVal, getPersistenceManagerFactory());
        }
        return retVal;
      } catch (InvocationTargetException ex) {
        throw ex.getTargetException();
      } finally {
        PersistenceManagerFactoryUtils.doReleasePersistenceManager(
            pm, getPersistenceManagerFactory());
      }
    }
 @Override
 public void preHandle(WebRequest request) throws DataAccessException {
   if (TransactionSynchronizationManager.hasResource(getPersistenceManagerFactory())) {
     // Do not modify the PersistenceManager: just mark the request accordingly.
     String participateAttributeName = getParticipateAttributeName();
     Integer count =
         (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
     int newCount = (count != null ? count + 1 : 1);
     request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
   } else {
     logger.debug("Opening JDO PersistenceManager in OpenPersistenceManagerInViewInterceptor");
     PersistenceManager pm =
         PersistenceManagerFactoryUtils.getPersistenceManager(
             getPersistenceManagerFactory(), true);
     TransactionSynchronizationManager.bindResource(
         getPersistenceManagerFactory(), new PersistenceManagerHolder(pm));
   }
 }
 @Override
 public void afterCompletion(WebRequest request, Exception ex) throws DataAccessException {
   String participateAttributeName = getParticipateAttributeName();
   Integer count =
       (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
   if (count != null) {
     // Do not modify the PersistenceManager: just clear the marker.
     if (count > 1) {
       request.setAttribute(participateAttributeName, count - 1, WebRequest.SCOPE_REQUEST);
     } else {
       request.removeAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST);
     }
   } else {
     PersistenceManagerHolder pmHolder =
         (PersistenceManagerHolder)
             TransactionSynchronizationManager.unbindResource(getPersistenceManagerFactory());
     logger.debug("Closing JDO PersistenceManager in OpenPersistenceManagerInViewInterceptor");
     PersistenceManagerFactoryUtils.releasePersistenceManager(
         pmHolder.getPersistenceManager(), getPersistenceManagerFactory());
   }
 }
 protected PersistenceManager getPersistenceManager() {
   return PersistenceManagerFactoryUtils.getPersistenceManager(pmf, true);
 }