Reputation: 449
I know it is possible to change the JPA implementation in use by Spring Boot, the default is to use Hibernate, but it's also possible to user others, like EclipseLink. It is possible to find, at application runtime, which JPA implementation is being used, and also discover which SQL dialect is currently in use (like MySQL, PostgreSQL, Oracle)?
Upvotes: 2
Views: 1670
Reputation: 1789
Another possible solution would be to inspect the JDBC string from the application.yml file :-)
Upvotes: 1
Reputation: 219
You could dig through the AutowireCapableBeanFactory. You could get the JpaBaseConfiguration.class bean. Then check the jpaVendorAdapter and the jpaDialect. That may work. Here is an example @RestController.
@RestController
class JpaConfigResource {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping("/jpa")
Map<String, String> getJpaConfig() {
JpaBaseConfiguration jpaConfig = null;
String jpaVendorAdapter = "Not Found";
String jpaDialect = "Not Found";
Map<String, String> result = new HashMap<>();
AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
if (autowireCapableBeanFactory != null) {
jpaConfig = autowireCapableBeanFactory.getBean(JpaBaseConfiguration.class);
} else {
System.out.println("autowireCapableBeanFactory was not found...");
}
if (jpaConfig != null) {
jpaVendorAdapter = jpaConfig.jpaVendorAdapter().getClass().getName();
jpaDialect = jpaConfig.jpaVendorAdapter().getJpaDialect().getClass().getName();
} else {
System.out.println("jpaConfig was not found...");
}
result.put("jpaVendorAdapter", jpaVendorAdapter);
result.put("jpaDialect", jpaDialect);
System.out.println("result => " + result.toString());
return result;
}
}
Upvotes: 1
Reputation: 1569
As stated by @Prabin, if you have access to the application logs, you should be able to grep for 'dialect' and come away with both the JPA Vendor and the Dialect in use.
2019-04-17 02:02:55.061 INFO 12724 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.SQLServer2012Dialect
If you have access to the code, the easier thing to do would just be to review the configuration, but since you asked about programmatic determination, there are a couple of things you could do (assuming you can access Spring Beans in your code either via the ApplicationContext
or by injection).
Using the ApplicationContext
to access the JpaVendorAdapter
Bean I can determine my JPA vendor to be org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
, but the dialect details are less helpful:
public static void main( String[] args ) {
SpringApplication springApplication = new SpringApplication( DevicePeersApplication.class );
ConfigurableApplicationContext appContext = springApplication.run( args );
JpaVendorAdapter jpaVendorAdapter = appContext.getBean( JpaVendorAdapter.class );
log.debug( "JPA Vendor Adapter: {}", jpaVendorAdapter.getClass().getName() );
log.debug( "JPA Dialect: {}", jpaVendorAdapter.getJpaDialect().getClass().getName() );
...
}
2019-04-17 02:02:59.226 DEBUG 12724 --- [ main] c.c.n.d.Application : JPA Vendor Adapter: org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
2019-04-17 02:02:59.226 DEBUG 12724 --- [ main] c.c.n.d.Application : JPA Dialect: org.springframework.orm.jpa.vendor.HibernateJpaDialect
Knowing that the JpaVendorAdapter
is org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
, I now know that the properties on the EntityManagerFactory
that I'm interested in will be prefixed with hibernate.
, in your case specifically hibernate.dialect
. You will have to look up the specifics for alternative JPA implementations like EclipseLink.
EntityManagerFactory entityManagerFactory = appContext.getBean( "entityManagerFactory", EntityManagerFactory.class );
String dialect = (String) entityManagerFactory.getProperties().getOrDefault( "hibernate.dialect", "" );
log.debug( "{}={}", "hibernate.dialect", dialect );
2019-04-17 02:02:59.228 DEBUG 12724 --- [ main] c.c.n.d.Application : hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
For completeness, you could pull all Hibernate-specific properties with the following, replacing 'hibernate.' with another property prefix as needed for other JPA implementations:
entityManagerFactory
.getProperties()
.entrySet()
.stream()
.filter( entry -> entry.getKey().startsWith( "hibernate." ) )
.forEach( entry -> log.debug( entry.toString() ) );
Finally, since JpaVendorAdapter
and EntityManagerFactory
are Spring Beans, you could just inject them into another part of your code and deal with them there:
@Autowired
JpaVendorAdapter jpaVendorAdapter;
@Autowired
EntityManagerFactory entityManagerFactory;
void myMethod() {
entityManagerFactory.getProperties()...
}
Upvotes: 2