You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dw...@apache.org on 2009/07/30 16:16:09 UTC
svn commit: r799277 -
/geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java
Author: dwoods
Date: Thu Jul 30 14:16:09 2009
New Revision: 799277
URL: http://svn.apache.org/viewvc?rev=799277&view=rev
Log:
GERONIMO-4410 - Maintain 1.0 behavior while allowing 2.0 required behavior of trying each discovered provider. Merging in from EA5 branch.
Modified:
geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java
Modified: geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java?rev=799277&r1=799276&r2=799277&view=diff
==============================================================================
--- geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java (original)
+++ geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java Thu Jul 30 14:16:09 2009
@@ -59,9 +59,9 @@
/**
* Create and return an EntityManagerFactory for the named persistence unit.
*
- * @param persistenceUnitName The name of the persistence unit
- * @return The factory that creates EntityManagers configured according to the
- * specified persistence unit
+ * @param persistenceUnitName Name of the persistence unit
+ * @return The factory for the specified persistence unit or null if none
+ * are applicable.
*/
public static EntityManagerFactory createEntityManagerFactory(
String persistenceUnitName) {
@@ -69,68 +69,112 @@
}
/**
- * Create and return an EntityManagerFactory for the named persistence unit using the
- * given properties.
+ * Create and return an EntityManagerFactory for the named persistence unit
+ * using the given properties.
*
- * @param persistenceUnitName The name of the persistence unit
- * @param properties Additional properties to use when creating the factory. The values of
- * these properties override any values that may have been configured
- * elsewhere.
- * @return The factory that creates EntityManagers configured according to the
- * specified persistence unit.
+ * @param persistenceUnitName Name of the persistence unit
+ * @param properties Additional properties to use when creating the
+ * persistence unit factory. These properties override any
+ * values that have been configured elsewhere.
+ * @return The factory for the specified persistence unit or null if none
+ * are applicable.
*/
public static EntityManagerFactory createEntityManagerFactory(
String persistenceUnitName, Map properties) {
+
EntityManagerFactory factory = null;
- if (properties == null) {
- properties = Collections.EMPTY_MAP;
+ Map props = properties;
+ if (props == null) {
+ props = Collections.EMPTY_MAP;
}
+ // get the discovered set of providers
+ PersistenceProviderResolver resolver =
+ PersistenceProviderResolverHolder.getPersistenceProviderResolver();
+ // following will throw PersistenceExceptions for invalid services
+ List<PersistenceProvider> providers = resolver.getPersistenceProviders();
+
/*
- * Geronimo/OpenJPA unique behavior - Start by loading a provider
- * explicitly specified in properties. The spec doesn't seem to forbid
- * providers that are not deployed as a service.
+ * Geronimo/OpenJPA 1.0 unique behavior - Start by loading a provider
+ * explicitly specified in the properties and return any exceptions.
+ * The spec doesn't forbid providers that aren't a service - it only
+ * states that they "should" be implemented as services in Sect. 9.2.
+ *
+ * For 2.0 - We only perform the above behavior if the specified
+ * provider is not in the discovered list.
+ *
+ * Note: This special non-spec defined case will rethrow any encountered
+ * Exceptions as a PersistenceException.
*/
- Object providerName = properties.get(PERSISTENCE_PROVIDER_PROPERTY);
- if (providerName instanceof String) {
- factory = createFactory(
+ Object providerName = props.get(PERSISTENCE_PROVIDER_PROPERTY);
+ if ((providerName != null) && (providerName instanceof String)) {
+ boolean isLoaded = false;
+ // search the discovered providers for this explicit provider
+ for (PersistenceProvider provider : providers) {
+ if (provider.getClass().getName().compareTo(providerName.toString()) == 0) {
+ isLoaded = true;
+ break;
+ }
+ }
+ /*
+ * Only try to explicitly create this provider if we didn't
+ * find it as a service, while rethrowing any exceptions to
+ * match the old 1.0 behavior
+ */
+ if (!isLoaded) {
+ factory = createFactory(
providerName.toString(),
persistenceUnitName,
- properties);
+ props);
+ if (factory != null) {
+ return factory;
+ }
+ }
}
-
- if (factory == null) {
- /*
- * Now, the default behavior of loading a provider from our resolver
- */
- PersistenceProviderResolver resolver =
- PersistenceProviderResolverHolder.getPersistenceProviderResolver();
- List<PersistenceProvider> providers = resolver.getPersistenceProviders();
+
+ /*
+ * Now, the default behavior of loading a provider from our resolver
+ * Note: Change in behavior from 1.0, which always returned exceptions:
+ * Spec states that a provider "must" return null if it
+ * cannot fulfill an EMF request, so ignore any exceptions
+ * that are thrown if we have more than one provider,
+ * so the other providers have a chance to return an EMF.
+ * Otherwise, return any exceptions and rethrow/wrapper as a
+ * PersistenceException if needed to match 1.0 behavior.
+ */
+ if (providers.size() == 1) {
+ // allow any exceptions to pass thru to caller
+ return providers.get(0).createEntityManagerFactory(
+ persistenceUnitName, props);
+ } else {
for (PersistenceProvider provider : providers) {
try {
factory = provider.createEntityManagerFactory(
- persistenceUnitName, properties);
+ persistenceUnitName, props);
} catch (Exception e) {
- // TODO - Grey area of Spec - mimic old 1.0 behavior for now
- throw new PersistenceException("Provider error. Provider: " + providerName, e);
+ // ignore and give other providers a chance
}
if (factory != null) {
- break;
+ return factory;
}
}
}
- // spec doesn't mention any exceptions thrown by this method if no emf
- return factory;
+ /*
+ * Spec doesn't mention any exceptions thrown by this method if no emf
+ * returned, but old 1.0 behavior always generated an EMF or exception.
+ */
+ throw new PersistenceException("No Persistence providers found for PU="
+ + persistenceUnitName);
}
/*
* Geronimo/OpenJPA private helper code for PERSISTENCE_PROVIDER_PROPERTY
+ * @return EntityManagerFactory or null
+ * @throws PersistenceException
*/
- private static EntityManagerFactory createFactory(
- String providerName,
- String persistenceUnitName,
- Map properties)
+ private static EntityManagerFactory createFactory(String providerName,
+ String persistenceUnitName, Map properties)
throws PersistenceException {
Class<?> providerClass;
@@ -140,13 +184,15 @@
try {
providerClass = Class.forName(providerName, true, cl);
} catch (Exception e) {
- throw new PersistenceException("Invalid or inaccessible provider class: " + providerName, e);
+ throw new PersistenceException("Invalid or inaccessible explicit provider class: " +
+ providerName, e);
}
try {
PersistenceProvider provider = (PersistenceProvider) providerClass.newInstance();
return provider.createEntityManagerFactory(persistenceUnitName, properties);
} catch (Exception e) {
- throw new PersistenceException("Provider error. Provider: " + providerName, e);
+ throw new PersistenceException("Explicit error returned from provider: " +
+ providerName, e);
}
}