Martin Andersson
Martin Andersson

Reputation: 19623

Check during runtime which persistence provider a Java EE server is using?

I am not looking to find out whether or not a class has been loaded using low-level Reflection API. This question has been posted here and has some answers. I want to use "clean code", preferably using an API as specified in a Java EE specification (for example, JPA 2.1).

My real problem is that I need to write a patch that applies only for Hibernate.

Upvotes: 0

Views: 751

Answers (1)

Martin Andersson
Martin Andersson

Reputation: 19623

See the Java Persistence 2.1 specification, section "9.3 Determining the Available Persistence Providers".

Example

PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();
List<PersistenceProvider> providers = resolver.getPersistenceProviders();

Note that there exists a Persistence.PERSISTENCE_PROVIDER (String) and a Persistence.providers (Set) but these fields has been deprecated according to their JavaDoc.

The PersistenceProvider interface doesn't say much. But the class behind the interface reveals the provider.

In GlassFish 4.0.1-b08-m1 that bundles EclipseLink 2.5.2, only one provider is returned: org.eclipse.persistence.jpa.PersistenceProvider.

In WildFly 8.1.0 that bundles Hibernate 4.3.5, two providers are returned. The second provider's class is org.hibernate.ejb.HibernatePersistence (order may be machine dependent?). According to the class JavaDoc, it has been deprecated in favor of the first provider in the List: org.hibernate.jpa.HibernatePersistenceProvider.

Note that the JPA specification emphasize that it might not be safe to cache this information:

In dynamic environments (e.g., OSGi-based environments, containers based on dynamic kernels, etc.), the list of persistence providers may change.

Note also that PersistenceProviderResolver.getPersistenceProviders() is used to " determine the list of available persistence providers". I have not yet understood how to determine the persistence provider in use. For example, in WildFly I would like to get hold of just one provider, not two.

Java 1.8 Solution

// "providers" is the variable declared in the example at the beginning
boolean usingHibernate = providers.stream()
        .map(Object::getClass)
        .map(Class::getName)
        .anyMatch(str -> str.startsWith("org.hibernate"));

Java 1.7 Solution

boolean usingHibernate = false;

for (PersistenceProvider p : providers) {
    if (p.getClass().getName().startsWith("org.hibernate")) {
        usingHibernate = true;
        break;
    }
}

Upvotes: 2

Related Questions