首页 > 解决方案 > 如何以编程方式发现 Spring Boot 使用的 JPA 实现和 SQL 方言?

问题描述

我知道可以更改 Spring Boot 使用的 JPA 实现,默认使用 Hibernate,但也可以使用其他用户,例如 EclipseLink。可以在应用程序运行时找到正在使用的 JPA 实现,还可以发现当前正在使用的 SQL 方言(如 MySQL、PostgreSQL、Oracle)?

标签: javaspringspring-bootspring-data-jpaspring-jdbc

解决方案


正如@Prabin 所述,如果您有权访问应用程序日志,您应该能够使用 grep 查找“方言”并同时使用 JPA 供应商和方言。

2019-04-17 02:02:55.061  INFO 12724 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.SQLServer2012Dialect

如果您可以访问代码,那么更容易做的就是查看配置,但是由于您询问了编程确定,您可以做几件事(假设您可以通过以下方式访问代码中的 Spring Beans或ApplicationContext通过注射)。

使用ApplicationContext访问JpaVendorAdapterBean 我可以确定我的 JPA 供应商是org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter,但方言详细信息不太有用:

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

知道了JpaVendorAdapterorg.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter,我现在知道EntityManagerFactory我感兴趣的属性将带有前缀hibernate.,特别是在您的情况下hibernate.dialect。您将不得不查找替代 JPA 实现(如 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

为了完整起见,您可以使用以下内容提取所有特定于 Hibernate 的属性,替换“hibernate”。使用其他 JPA 实现所需的另一个属性前缀:

entityManagerFactory
            .getProperties()
            .entrySet()
            .stream()
            .filter( entry -> entry.getKey().startsWith( "hibernate." ) )
            .forEach( entry -> log.debug( entry.toString() ) );

最后,由于JpaVendorAdapterandEntityManagerFactory是 Spring Bean,您可以将它们注入代码的另一部分并在那里处理它们:

@Autowired
JpaVendorAdapter jpaVendorAdapter;

@Autowired
EntityManagerFactory entityManagerFactory;

void myMethod() {
    entityManagerFactory.getProperties()...
}

推荐阅读