简体   繁体   中英

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 .

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 (eg, 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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM