How to programmatically discover the JPA implementation and SQL dialect being used by Spring Boot?

André Shevantes :

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)?

Philip Wrage :

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()...
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=143050&siteId=1