1
votes

Intégration du pilote JDBC Elastic Search avec Hibernate / Spring Boot

J'essaye d'intégrer le pilote élastique "org.elasticsearch.xpack.sql.jdbc.EsDriver" de

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

dans mon application de démarrage de printemps en utilisant Hibernate.

Dans mon bean de configuration de printemps, j'ai ce qui suit:

    @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();
    }

Cependant, lorsque j'exécute ce code, j'obtiens l'exception suivante:

<dependency>
  <groupId>org.elasticsearch.plugin</groupId>
  <artifactId>x-pack-sql-jdbc</artifactId>
  <version>7.10.0</version>
</dependency>

Je suppose que c'est parce que le pilote n'est pas compatible avec la mise en veille prolongée. Ai-je raison ou y a-t-il une autre configuration à effectuer pour contourner le problème?

Il existe également un pilote JDBC disponible dans le commerce ici: https://www.cdata.com/drivers/elasticsearch/jdbc/

Quelqu'un at-il une expérience avec ce pilote et sa compatibilité avec Hibernate?


0 commentaires

3 Réponses :


0
votes

Je n'ai aucune connaissance du pilote ElasticSearch, mais je vais vous dire pourquoi vous obtenez l'erreur.

Votre erreur est: Causée par: java.lang.ClassCastException: org.elasticsearch.xpack.sql.jdbc.EsDriver ne peut pas être converti en org.hibernate.dialect.Dialect

C'est parce que vous avez un problème dans vos propriétés:

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

EsDrver.class.getName () n'est pas un dialecte de mise en veille prolongée.

Un exemple de dialecte d'hibernation est: org.hibernate.dialect.MySQL5Dialect

Veuillez lire https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-jdbc.html

Voyant que vous utilisez Springboot, vous n'aurez peut-être même pas à configurer manuellement la source de données / le gestionnaire d'entités. Le simple fait d'ajouter la dépendance la configurera automatiquement.


0 commentaires

0
votes

Il n'y a pas de dialecte pour le dialecte ElasticSearch SQL, mais vous pouvez essayer d'utiliser org.hibernate.dialect.SQLServerDialect comme suggéré dans https://www.cdata.com/kb/tech/elasticsearch-jdbc-hibernate.rst

En fin de compte, vous devrez probablement remplacer quelques configurations dans le dialecte pour s'adapter au dialecte SQL pris en charge par ES.


0 commentaires

0
votes

J'ai donc trouvé que org.hibernate.dialect.H2Dialect ou org.hibernate.dialect.PostgreSQL9Dialect fonctionnent, mais seulement jusqu'à un certain point.

Tout d'abord, vous devez également inclure des guillemets doubles dans les noms d'entités:

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}

De plus, j'ai trouvé que la configuration de maxRows ne fonctionne pas. Pour une raison quelconque, cette valeur n'est pas liée à une limite dans le Sql généré:

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

Quelqu'un a des idées sur pourquoi cela pourrait être?


0 commentaires