public static EntityManagerFactory createEntityManagerFactory()

in geronimo-jpa_2.0_spec/src/main/java/javax/persistence/Persistence.java [78:191]


    public static EntityManagerFactory createEntityManagerFactory(
            String persistenceUnitName, Map properties) {

        EntityManagerFactory factory = null;
        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 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 propVal = props.get(PERSISTENCE_PROVIDER_PROPERTY);
        if ((propVal != null) && (propVal instanceof String)) {
            boolean isLoaded = false;
            String providerName = propVal.toString();
            // search the discovered providers for this explicit provider
            for (PersistenceProvider provider : providers) {
                if (provider.getClass().getName().compareTo(providerName) == 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,
                    props);
                if (factory != null) {
                    return factory;
                }
            }
        }

        /*
         * Now, the default JPA2 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 that if we have more than one
         *   provider, then the other providers have a chance to return an EMF.
         *   Now, we will return any exceptions wrapped in a
         *   PersistenceException to match 1.0 behavior and provide more
         *   diagnostics to the end user.
         */

        // capture any provider returned exceptions
        Map<String, Throwable> exceptions = new HashMap<String, Throwable>();
        // capture the provider names to use in the exception text if needed
        StringBuffer foundProviders = null;

        for (PersistenceProvider provider : providers) {
            String providerName = provider.getClass().getName();
            try {
                factory = provider.createEntityManagerFactory(persistenceUnitName, props);
            } catch (Exception e) {
                // capture the exception details and give other providers a chance
                exceptions.put(providerName, e);
            }
            if (factory != null) {
                // we're done
                return factory;
            } else {
                // update the list of providers we have tried
                if (foundProviders == null) {
                    foundProviders = new StringBuffer(providerName);
                } else {
                    foundProviders.append(", ");
                    foundProviders.append(providerName);
                }
            }
        }

        // make sure our providers list is initialized for the exceptions below
        if (foundProviders == null) {
            foundProviders = new StringBuffer("NONE");
        }

        /*
         * 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.
         */
        if (exceptions.isEmpty()) {
            // throw an exception with the PU name and providers we tried
            throw new PersistenceException("No persistence providers available for \"" + persistenceUnitName +
                "\" after trying the following discovered implementations: " + foundProviders);
        } else {
            // we encountered one or more exceptions, so format and throw as a single exception
            throw createPersistenceException(
                "Explicit persistence provider error(s) occurred for \"" + persistenceUnitName +
                "\" after trying the following discovered implementations: " + foundProviders,
                exceptions);
        }
    }