Как программно обнаружить реализацию JPA и диалект SQL, используемый Spring Boot? - PullRequest
2 голосов
/ 17 апреля 2019

Я знаю, что можно изменить реализацию JPA, используемую Spring Boot, по умолчанию используется Hibernate, но также можно использовать и другие, например EclipseLink.Можно во время выполнения приложения определить, какая реализация JPA используется, а также определить, какой диалект SQL используется в настоящее время (например, MySQL, PostgreSQL, Oracle)?

Ответы [ 2 ]

2 голосов
/ 17 апреля 2019

Как заявляет @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, я могу определить моего поставщика 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

Зная, что JpaVendorAdapter равен org.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() ) );

Наконец, поскольку JpaVendorAdapter и EntityManagerFactory являются Spring Beans, вы можете просто внедрить их в другую часть вашего кода и работать с ними там:

@Autowired
JpaVendorAdapter jpaVendorAdapter;

@Autowired
EntityManagerFactory entityManagerFactory;

void myMethod() {
    entityManagerFactory.getProperties()...
}
1 голос
/ 17 апреля 2019

Вы можете копаться в AutowireCapableBeanFactory.Вы можете получить компонент JpaBaseConfiguration.class.Затем проверьте 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;
  }
}
...