@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()); } }