如何以编程方式发现Spring Boot使用的JPA实现和SQL方言?

问题描述 投票:2回答:2

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

java spring spring-boot spring-data-jpa spring-jdbc
2个回答
2
投票

正如@Prabin所述,如果您有权访问应用程序日志,您应该可以使用“方言”,并使用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访问JpaVendorAdapter Bean我可以确定我的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() ) );

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

@Autowired
JpaVendorAdapter jpaVendorAdapter;

@Autowired
EntityManagerFactory entityManagerFactory;

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

1
投票

您可以挖掘AutowireCapableBeanFactory。你可以得到JpaBaseConfiguration.class bean。然后检查jpaVendorAdapter和jpaDialect。这可能有用。这是一个示例@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;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.