我不想查明是否已使用低级反射 API 加载类。此问题已发布here并有一些答案。我想使用“干净的代码”,最好使用 Java EE 规范中指定的 API(例如 JPA 2.1 )。
我真正的问题是我需要编写一个仅适用于 Hibernate
的补丁。
最佳答案
请参阅Java Persistence 2.1规范,“9.3 确定可用持久性提供程序”部分。
示例
PersistenceProviderResolver resolver = PersistenceProviderResolverHolder.getPersistenceProviderResolver();
List<PersistenceProvider> providers = resolver.getPersistenceProviders();
请注意,存在一个 Persistence.PERSISTENCE_PROVIDER
(String)和一个 Persistence.providers
(Set)但根据其 JavaDoc,这些字段已被弃用。
PersistenceProvider
界面就不多说了。但接口(interface)背后的类揭示了提供者。
在捆绑 EclipseLink 2.5.2 的 GlassFish 4.0.1-b08-m1 中,仅返回一个提供程序:org.eclipse.persistence.jpa.PersistenceProvider
.
在捆绑 Hibernate 4.3.5 的 WildFly 8.1.0 中,返回两个 提供程序。第二个提供者的类别是 org.hibernate.ejb.HibernatePersistence
(顺序可能取决于机器?)。根据 JavaDoc 类,它已被弃用,取而代之的是列表中的第一个提供程序: org.hibernate.jpa.HibernatePersistenceProvider
.
请注意 JPA specification强调缓存此信息可能不安全:
In dynamic environments (e.g., OSGi-based environments, containers based on dynamic kernels, etc.), the list of persistence providers may change.
另请注意,PersistenceProviderResolver.getPersistenceProviders()
用于“确定可用持久性提供程序的列表”。我尚未了解如何确定正在使用的持久性提供程序。例如,在 WildFly 中,我只想找到一个提供商,而不是两个。
Java 1.8 解决方案
// "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 解决方案
boolean usingHibernate = false;
for (PersistenceProvider p : providers) {
if (p.getClass().getName().startsWith("org.hibernate")) {
usingHibernate = true;
break;
}
}
关于java - 在运行时检查 Java EE 服务器正在使用哪个持久性提供程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24875442/