【问题标题】:Integrating Elastic Search JDBC driver with Hibernate / Spring Boot将 Elastic Search JDBC 驱动程序与 Hibernate / Spring Boot 集成
【发布时间】:2020-11-12 11:18:31
【问题描述】:

我正在尝试从

集成弹性驱动程序“org.elasticsearch.xpack.sql.jdbc.EsDriver”
<dependency>
  <groupId>org.elasticsearch.plugin</groupId>
  <artifactId>x-pack-sql-jdbc</artifactId>
  <version>7.10.0</version>
</dependency>

使用 Hibernate 进入我的 Spring Boot 应用程序。

在我的 spring 配置 bean 中,我有以下内容:


    @Bean
    @ConfigurationProperties(prefix = "db.elastic")
    @Qualifier("elasticDataSource")
    @Primary
    public DataSource elasticDataSource() {
        return DataSourceBuilder.create()
                .build();
    }

    public LocalContainerEntityManagerFactoryBean elasticEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        Map<String, Object> properties = new HashMap<>();
        properties.put(AvailableSettings.HBM2DDL_AUTO, "none");
        properties.put(AvailableSettings.HBM2DLL_CREATE_SCHEMAS, "false");
        properties.put(AvailableSettings.DIALECT, org.elasticsearch.xpack.sql.jdbc.EsDriver.class.getName());
        return builder
                .dataSource(elasticDataSource())
                .packages(Issuer.class)
                .persistenceUnit("elastic")
                .properties(properties)
                .build();
    }

但是,当我运行此代码时,出现以下异常:

Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:179)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
    ... 16 common frames omitted
Caused by: org.hibernate.HibernateException: Unable to construct requested dialect [org.elasticsearch.xpack.sql.jdbc.EsDriver]
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.constructDialect(DialectFactoryImpl.java:84)
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:51)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    ... 33 common frames omitted
Caused by: java.lang.ClassCastException: org.elasticsearch.xpack.sql.jdbc.EsDriver cannot be cast to org.hibernate.dialect.Dialect
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.constructDialect(DialectFactoryImpl.java:74)
    ... 38 common frames omitted

我认为这是因为驱动程序与休眠不兼容。我是正确的还是必须进行一些其他配置才能解决该问题?

这里还有一个商用的JDBC驱动:https://www.cdata.com/drivers/elasticsearch/jdbc/

有没有人使用过这个驱动程序以及它与 Hibernate 的兼容性?

【问题讨论】:

    标签: java spring-boot hibernate elasticsearch jdbc


    【解决方案1】:

    我对 ElasticSearch 驱动程序一无所知,但我会告诉你为什么会出现错误。

    你的错误是:Caused by: java.lang.ClassCastException: org.elasticsearch.xpack.sql.jdbc.EsDriver cannot be cast to org.hibernate.dialect.Dialect

    这是因为你的属性有问题:

    properties.put(AvailableSettings.DIALECT, org.elasticsearch.xpack.sql.jdbc.EsDriver.class.getName());

    EsDrver.class.getName() 不是 Hibernate 方言。

    一个示例休眠方言是:org.hibernate.dialect.MySQL5Dialect

    请阅读https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-jdbc.html

    看到您使用的是 Springboot,您甚至可能不必手动配置数据源/实体管理器。只需添加依赖项即可自动配置它。

    【讨论】:

      【解决方案2】:

      ElasticSearch SQL 方言没有方言,但您可以尝试使用org.hibernate.dialect.SQLServerDialect,如https://www.cdata.com/kb/tech/elasticsearch-jdbc-hibernate.rst 中所建议的那样

      最后,您可能必须覆盖方言中的一些配置以适应 ES 支持的 SQL 方言。

      【讨论】:

        【解决方案3】:

        所以我发现 org.hibernate.dialect.H2Dialect 或 org.hibernate.dialect.PostgreSQL9Dialect 可以工作,但只是在一定程度上。

        首先,您还必须在实体名称中包含双引号:

        @Data
        @Table(name = "\"mytable\"")
        @Entity
        public class MyTable {
        }
        

        此外,我发现设置 maxRows 不起作用。由于某种原因,此值在生成的 Sql 中不受限制:

        18:14:29.320 [http-nio-8081-exec-1] DEBUG org.hibernate.SQL - 
            select
                mytabl_.NAME as col_0_0_ 
            from
                "mytable" mytabl_
            order by
                mytabl_.NAME asc limit ?
        18:14:29.651 [http-nio-8081-exec-1] WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: null
        18:14:29.651 [http-nio-8081-exec-1] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - line 1:108: mismatched input '?' expecting {'ALL', INTEGER_VALUE}
        18:14:29.658 [http-nio-8081-exec-1] WARN  g.e.SimpleDataFetcherExceptionHandler - Exception while fetching data (/Issuers) : line 1:108: mismatched input '?' expecting {'ALL', INTEGER_VALUE}
        org.hibernate.JDBCException: line 1:108: mismatched input '?' expecting {'ALL', INTEGER_VALUE}
        

        有人知道为什么会这样吗?

        【讨论】:

          猜你喜欢
          • 2016-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-24
          • 2021-07-07
          • 2020-10-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多