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.HashMap ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import java.util.Properties ; 27 28 import javax.persistence.EntityManager; 29 import javax.persistence.EntityManagerFactory; 30 import javax.persistence.PersistenceException; 31 import javax.persistence.spi.PersistenceProvider; 32 import javax.persistence.spi.PersistenceUnitInfo; 33 import javax.sql.DataSource ; 34 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 import org.springframework.beans.BeanUtils; 39 import org.springframework.beans.factory.DisposableBean; 40 import org.springframework.beans.factory.FactoryBean; 41 import org.springframework.beans.factory.InitializingBean; 42 import org.springframework.dao.DataAccessException; 43 import org.springframework.dao.support.PersistenceExceptionTranslator; 44 import org.springframework.util.Assert; 45 import org.springframework.util.ClassUtils; 46 import org.springframework.util.CollectionUtils; 47 import org.springframework.util.ObjectUtils; 48 49 75 public abstract class AbstractEntityManagerFactoryBean implements 76 FactoryBean, InitializingBean, DisposableBean, EntityManagerFactoryInfo, PersistenceExceptionTranslator { 77 78 79 protected final Log logger = LogFactory.getLog(getClass()); 80 81 private PersistenceProvider persistenceProvider; 82 83 private String persistenceUnitName; 84 85 private final Map jpaPropertyMap = new HashMap (); 86 87 private Class <? extends EntityManager> entityManagerInterface; 88 89 private JpaDialect jpaDialect; 90 91 private JpaVendorAdapter jpaVendorAdapter; 92 93 94 public EntityManagerFactory nativeEntityManagerFactory; 95 96 private EntityManagerFactory entityManagerFactory; 97 98 99 108 public void setPersistenceProviderClass(Class <? extends PersistenceProvider> persistenceProviderClass) { 109 Assert.isAssignable(PersistenceProvider.class, persistenceProviderClass); 110 this.persistenceProvider = (PersistenceProvider) BeanUtils.instantiateClass(persistenceProviderClass); 111 } 112 113 122 public void setPersistenceProvider(PersistenceProvider persistenceProvider) { 123 this.persistenceProvider = persistenceProvider; 124 } 125 126 public PersistenceProvider getPersistenceProvider() { 127 return this.persistenceProvider; 128 } 129 130 137 public void setPersistenceUnitName(String persistenceUnitName) { 138 this.persistenceUnitName = persistenceUnitName; 139 } 140 141 public String getPersistenceUnitName() { 142 return this.persistenceUnitName; 143 } 144 145 153 public void setJpaProperties(Properties jpaProperties) { 154 CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.jpaPropertyMap); 155 } 156 157 164 public void setJpaPropertyMap(Map jpaProperties) { 165 if (jpaProperties != null) { 166 this.jpaPropertyMap.putAll(jpaProperties); 167 } 168 } 169 170 176 public Map getJpaPropertyMap() { 177 return this.jpaPropertyMap; 178 } 179 180 189 public void setEntityManagerInterface(Class <? extends EntityManager> entityManagerInterface) { 190 Assert.isAssignable(EntityManager.class, entityManagerInterface); 191 this.entityManagerInterface = entityManagerInterface; 192 } 193 194 public Class <? extends EntityManager> getEntityManagerInterface() { 195 return this.entityManagerInterface; 196 } 197 198 205 public void setJpaDialect(JpaDialect jpaDialect) { 206 this.jpaDialect = jpaDialect; 207 } 208 209 public JpaDialect getJpaDialect() { 210 return this.jpaDialect; 211 } 212 213 219 public void setJpaVendorAdapter(JpaVendorAdapter jpaVendorAdapter) { 220 this.jpaVendorAdapter = jpaVendorAdapter; 221 } 222 223 224 public final void afterPropertiesSet() throws PersistenceException { 225 if (this.jpaVendorAdapter != null) { 226 if (this.persistenceProvider == null) { 227 this.persistenceProvider = this.jpaVendorAdapter.getPersistenceProvider(); 228 } 229 Map vendorPropertyMap = this.jpaVendorAdapter.getJpaPropertyMap(); 230 if (vendorPropertyMap != null) { 231 for (Iterator it = vendorPropertyMap.entrySet().iterator(); it.hasNext();) { 232 Map.Entry entry = (Map.Entry ) it.next(); 233 if (!this.jpaPropertyMap.containsKey(entry.getKey())) { 234 this.jpaPropertyMap.put(entry.getKey(), entry.getValue()); 235 } 236 } 237 } 238 if (this.entityManagerInterface == null) { 239 this.entityManagerInterface = this.jpaVendorAdapter.getEntityManagerInterface(); 240 } 241 if (this.jpaDialect == null) { 242 this.jpaDialect = this.jpaVendorAdapter.getJpaDialect(); 243 } 244 } 245 else { 246 if (this.entityManagerInterface == null) { 247 this.entityManagerInterface = EntityManager.class; 248 } 249 } 250 251 this.nativeEntityManagerFactory = createNativeEntityManagerFactory(); 252 if (this.jpaVendorAdapter != null) { 253 this.jpaVendorAdapter.postProcessEntityManagerFactory(this.nativeEntityManagerFactory); 254 } 255 256 this.entityManagerFactory = createEntityManagerFactoryProxy(this.nativeEntityManagerFactory); 261 } 262 263 270 protected EntityManagerFactory createEntityManagerFactoryProxy(EntityManagerFactory emf) { 271 Class [] ifcs = ClassUtils.getAllInterfaces(emf); 273 ifcs = (Class []) ObjectUtils.addObjectToArray(ifcs, EntityManagerFactoryInfo.class); 274 EntityManagerFactoryPlusOperations plusOperations = null; 275 if (getJpaDialect() != null && getJpaDialect().supportsEntityManagerFactoryPlusOperations()) { 276 plusOperations = getJpaDialect().getEntityManagerFactoryPlusOperations(emf); 277 ifcs = (Class []) ObjectUtils.addObjectToArray(ifcs, EntityManagerFactoryPlusOperations.class); 278 } 279 return (EntityManagerFactory) Proxy.newProxyInstance(getClass().getClassLoader(), ifcs, 280 new ManagedEntityManagerFactoryInvocationHandler(emf, this, plusOperations)); 281 } 282 283 289 protected abstract EntityManagerFactory createNativeEntityManagerFactory() throws PersistenceException; 290 291 292 301 public DataAccessException translateExceptionIfPossible(RuntimeException ex) { 302 return (this.jpaDialect != null ? this.jpaDialect.translateExceptionIfPossible(ex) : 303 EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex)); 304 } 305 306 public EntityManagerFactory getNativeEntityManagerFactory() { 307 return this.nativeEntityManagerFactory; 308 } 309 310 public PersistenceUnitInfo getPersistenceUnitInfo() { 311 return null; 312 } 313 314 public DataSource getDataSource() { 315 return null; 316 } 317 318 319 322 public EntityManagerFactory getObject() { 323 return this.entityManagerFactory; 324 } 325 326 public Class getObjectType() { 327 return (this.entityManagerFactory != null ? this.entityManagerFactory.getClass() : EntityManagerFactory.class); 328 } 329 330 public boolean isSingleton() { 331 return true; 332 } 333 334 335 338 public void destroy() { 339 logger.info("Closing JPA EntityManagerFactory for <" + persistenceUnitName + ">"); 340 this.entityManagerFactory.close(); 341 } 342 343 344 349 private static class ManagedEntityManagerFactoryInvocationHandler implements InvocationHandler { 350 351 private final EntityManagerFactory targetEntityManagerFactory; 352 353 private final EntityManagerFactoryInfo entityManagerFactoryInfo; 354 355 private final EntityManagerFactoryPlusOperations entityManagerFactoryPlusOperations; 356 357 private final JpaDialect jpaDialect; 358 359 public ManagedEntityManagerFactoryInvocationHandler(EntityManagerFactory targetEmf, 360 EntityManagerFactoryInfo emfInfo, EntityManagerFactoryPlusOperations entityManagerFactoryPlusOperations) { 361 362 this.targetEntityManagerFactory = targetEmf; 363 this.entityManagerFactoryInfo = emfInfo; 364 this.entityManagerFactoryPlusOperations = entityManagerFactoryPlusOperations; 365 this.jpaDialect = emfInfo.getJpaDialect(); 366 } 367 368 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 369 try { 370 if (method.getDeclaringClass().isAssignableFrom(EntityManagerFactoryInfo.class)) { 371 return method.invoke(this.entityManagerFactoryInfo, args); 372 } 373 if (method.getDeclaringClass().equals(EntityManagerFactoryPlusOperations.class)) { 374 return method.invoke(this.entityManagerFactoryPlusOperations, args); 375 } 376 Object retVal = method.invoke(this.targetEntityManagerFactory, args); 377 if (retVal instanceof EntityManager) { 378 EntityManager rawEntityManager = (EntityManager) retVal; 379 EntityManagerPlusOperations plusOperations = null; 380 if (this.jpaDialect != null && this.jpaDialect.supportsEntityManagerPlusOperations()) { 381 plusOperations = this.jpaDialect.getEntityManagerPlusOperations(rawEntityManager); 382 } 383 retVal = ExtendedEntityManagerCreator.createApplicationManagedEntityManager( 384 rawEntityManager, plusOperations, this.jpaDialect); 385 } 386 return retVal; 387 } 388 catch (InvocationTargetException ex) { 389 throw ex.getTargetException(); 390 } 391 } 392 } 393 394 } 395 | Popular Tags |