1 16 17 package org.springframework.orm.jpa; 18 19 import java.lang.reflect.InvocationHandler ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Proxy ; 23 import java.util.Map ; 24 25 import javax.persistence.EntityManager; 26 import javax.persistence.EntityManagerFactory; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 31 import org.springframework.util.CollectionUtils; 32 33 48 public abstract class SharedEntityManagerCreator { 49 50 59 public static EntityManager createSharedEntityManager(EntityManagerFactory emf) { 60 return createSharedEntityManager(emf, null); 61 } 62 63 74 public static EntityManager createSharedEntityManager(EntityManagerFactory emf, Map properties) { 75 Class [] entityManagerInterfaces = null; 76 if (emf instanceof EntityManagerFactoryInfo) { 77 EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf; 78 Class entityManagerInterface = emfInfo.getEntityManagerInterface(); 79 JpaDialect jpaDialect = emfInfo.getJpaDialect(); 80 if (jpaDialect != null && jpaDialect.supportsEntityManagerPlusOperations()) { 81 entityManagerInterfaces = new Class [] {entityManagerInterface, EntityManagerPlus.class}; 82 } 83 else { 84 entityManagerInterfaces = new Class [] {entityManagerInterface}; 85 } 86 } 87 else { 88 entityManagerInterfaces = new Class [] {EntityManager.class}; 89 } 90 return createSharedEntityManager(emf, properties, entityManagerInterfaces); 91 } 92 93 103 public static EntityManager createSharedEntityManager( 104 EntityManagerFactory emf, Map properties, Class ... entityManagerInterfaces) { 105 106 return (EntityManager) Proxy.newProxyInstance( 107 SharedEntityManagerCreator.class.getClassLoader(), 108 entityManagerInterfaces, 109 new SharedEntityManagerInvocationHandler(emf, properties)); 110 } 111 112 113 118 private static class SharedEntityManagerInvocationHandler implements InvocationHandler { 119 120 private final Log logger = LogFactory.getLog(getClass()); 121 122 private final EntityManagerFactory targetFactory; 123 124 private final Map properties; 125 126 public SharedEntityManagerInvocationHandler(EntityManagerFactory target, Map properties) { 127 this.targetFactory = target; 128 this.properties = properties; 129 } 130 131 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 132 134 if (method.getName().equals("equals")) { 135 return (proxy == args[0]); 137 } 138 else if (method.getName().equals("hashCode")) { 139 return hashCode(); 141 } 142 else if (method.getName().equals("isOpen")) { 143 return true; 145 } 146 else if (method.getName().equals("close")) { 147 return null; 149 } 150 else if (method.getName().equals("getTransaction")) { 151 throw new IllegalStateException ( 152 "Not allowed to create transaction on shared EntityManager - " + 153 "use Spring transactions or EJB CMT instead"); 154 } 155 else if (method.getName().equals("joinTransaction")) { 156 throw new IllegalStateException ( 157 "Not allowed to join transaction on shared EntityManager - " + 158 "use Spring transactions or EJB CMT instead"); 159 } 160 161 EntityManager target = 164 EntityManagerFactoryUtils.doGetTransactionalEntityManager(this.targetFactory, this.properties); 165 boolean isNewEm = false; 166 if (target == null) { 167 logger.debug("Creating new EntityManager for shared EntityManager invocation"); 168 target = (!CollectionUtils.isEmpty(this.properties) ? 169 this.targetFactory.createEntityManager(this.properties) : 170 this.targetFactory.createEntityManager()); 171 isNewEm = true; 172 } 173 174 try { 176 return method.invoke(target, args); 177 } 178 catch (InvocationTargetException ex) { 179 throw ex.getTargetException(); 180 } 181 finally { 182 if (isNewEm) { 183 target.close(); 184 } 185 } 186 } 187 } 188 189 } 190 | Popular Tags |