Update of /cvsroot/springframework/spring/tiger/src/org/springframework/orm/jpa
In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv12809/tiger/src/org/springframework/orm/jpa
Modified Files:
SharedEntityManagerCreator.java
Log Message:
@PersistenceContext of type TRANSACTION allows returned Query objects to be parameterized and executed as well
Index: SharedEntityManagerCreator.java
===================================================================
RCS file: /cvsroot/springframework/spring/tiger/src/org/springframework/orm/jpa/SharedEntityManagerCreator.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** SharedEntityManagerCreator.java 29 May 2008 00:35:13 -0000 1.9
--- SharedEntityManagerCreator.java 20 Oct 2008 22:10:36 -0000 1.10
***************
*** 25,28 ****
--- 25,29 ----
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
+ import javax.persistence.Query;
import org.apache.commons.logging.Log;
***************
*** 195,199 ****
// Invoke method on current EntityManager.
try {
! return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
--- 196,206 ----
// Invoke method on current EntityManager.
try {
! Object result = method.invoke(target, args);
! if (isNewEm && result instanceof Query) {
! result = Proxy.newProxyInstance(Query.class.getClassLoader(), new Class[] {Query.class},
! new DeferredQueryInvocationHandler((Query) result, target));
! isNewEm = false;
! }
! return result;
}
catch (InvocationTargetException ex) {
***************
*** 208,210 ****
--- 215,261 ----
}
+
+ /**
+ * Invocation handler that handles deferred Query objects created by
+ * non-transactional createQuery invocations on a shared EntityManager.
+ */
+ private static class DeferredQueryInvocationHandler implements InvocationHandler {
+
+ private final Query target;
+
+ private final EntityManager em;
+
+ private DeferredQueryInvocationHandler(Query target, EntityManager em) {
+ this.target = target;
+ this.em = em;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ // Invocation on Query 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 EntityManager proxy.
+ return hashCode();
+ }
+
+ // Invoke method on actual Query object.
+ try {
+ return method.invoke(this.target, args);
+ }
+ catch (InvocationTargetException ex) {
+ throw ex.getTargetException();
+ }
+ finally {
+ if (method.getName().equals("getResultList") || method.getName().equals("getSingleResult") ||
+ method.getName().equals("executeUpdate")) {
+ EntityManagerFactoryUtils.closeEntityManager(this.em);
+ }
+ }
+ }
+ }
+
}
|