hibernate-searchhibernate-search-6

How do i disable elastic search and fall back to local filesystem storage in hibernate search 6


I am using Hibernate 6 with Amazons opensearch server in production. When i'm testing locally i don't want to use the opensearch server, instead i want to use local-filesystem to store the index files.

However i can't hibernate search to use local-filesystem even when i explicitly set it with jpaProperties.put("hibernate.search.backend.directory.type", "local-filesystem"); while at the same time not setting the property hibernate.search.backend.uris. Before all the hibernate search properties can be programmatically set i get the following error on startup:

    default backend: 
        failures: 
          - HSEARCH400080: Unable to detect the Elasticsearch version running on the cluster: HSEARCH400007: Elasticsearch request failed: Connection refused: no further information
Request: GET  with parameters {}

I have the following maven dependencies:

<dependency>
    <groupId>org.hibernate.search</groupId>
    <artifactId>hibernate-search-mapper-orm</artifactId>
    <version>6.1.5.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.search</groupId>
    <artifactId>hibernate-search-backend-elasticsearch-aws</artifactId>
    <version>6.1.5.Final</version>
</dependency>

The following sets hibernate search and the lucene file destination path if using lucene only:

    private Properties initializeJpaProperties() {
        String luceneAbsoluteFilePath = useExternalElasticSearchServer ? null : setDefaultLuceneIndexBaseFilePath(); //Alleen relevant wanneer je geen elastic search gebruikt.
        Properties jpaProperties = new Properties();
        //---------------------------open search aws related-----------------------------------
        if(useExternalElasticSearchServer) {
            jpaProperties.put("hibernate.search.backend.aws.credentials.type", "static");
            jpaProperties.put("hibernate.search.backend.aws.credentials.access_key_id", awsId);
            jpaProperties.put("hibernate.search.backend.aws.credentials.secret_access_key", awsKey);
            jpaProperties.put("hibernate.search.backend.aws.region", openSearchAwsInstanceRegion);
            jpaProperties.put("hibernate.search.backend.aws.signing.enabled", true);
            jpaProperties.put("hibernate.search.backend.uris", elasticSearchHostAddress);
        }
        //--------------------------------------------------------------------------------------------
        jpaProperties.put("hibernate.search.automatic_indexing.synchronization.strategy", indexSynchronizationStrategy);
        jpaProperties.put("hibernate.search.backend.request_timeout", requestTimeout);
        jpaProperties.put("hibernate.search.backend.connection_timeout", elasticSearchConnectionTimeout);
        jpaProperties.put("hibernate.search.backend.read_timeout", readTimeout);
        jpaProperties.put("hibernate.search.backend.max_connections", maximumElasticSearchConnections);
        jpaProperties.put("hibernate.search.backend.max_connections_per_route", maximumElasticSearchConnectionsPerRout);
//        jpaProperties.put("hibernate.search.schema_management.strategy", schemaManagementStrategy);
        jpaProperties.put("hibernate.search.backend.thread_pool.size", maxPoolSize);
        jpaProperties.put("hibernate.search.backend.analysis.configurer", "class:config.EnhancedLuceneAnalysisConfig");
    //    jpaProperties.put("hibernate.search.backend.username", hibernateSearchUsername); //Alleen voor wanneer je elastic search lokaal draait
    //    jpaProperties.put("hibernate.search.backend.password", hibernateSearchPassword);
        if(!useExternalElasticSearchServer) {
            jpaProperties.put("hibernate.search.backend.directory.type", "local-filesystem");
            jpaProperties.put("hibernate.search.backend.directory.root", luceneAbsoluteFilePath);
            jpaProperties.put("hibernate.search.backend.lucene_version", "LUCENE_CURRENT");
            jpaProperties.put("hibernate.search.backend.io.writer.infostream", true);
        }
        jpaProperties.put("hibernate.jdbc.batch_size", defaultBatchSize);
        jpaProperties.put("spring.jpa.properties.hibernate.jdbc.batch_size", defaultBatchSize);
        jpaProperties.put("hibernate.order_inserts", "true");
        jpaProperties.put("hibernate.order_updates", "true");
        jpaProperties.put("hibernate.batch_versioned_data", "true");
//        log.info("The directory of the lucene index files is set to {}", luceneAbsoluteFilePath);
        return jpaProperties;
    }

    private String setDefaultLuceneIndexBaseFilePath() {
        String luceneRelativeFilePath = ServiceUtil.getOperatingSystemCompatiblePath("/data/lucene/indexes/default"); 
        StringBuilder luceneAbsoluteFilePath = new StringBuilder(System.getProperty("user.dir"));
        if(!StringUtils.isEmpty(luceneIndexBase)) {
            luceneRelativeFilePath = ServiceUtil.getOperatingSystemCompatiblePath(luceneIndexBase);
            String OSPathSeparator = ServiceUtil.getOperatingSystemFileSeparator();
            if(luceneRelativeFilePath.toCharArray()[0] != OSPathSeparator.charAt(0))
                luceneAbsoluteFilePath.append(OSPathSeparator);
            luceneAbsoluteFilePath.append(luceneRelativeFilePath);
            validateUserDefinedAbsolutePath(luceneRelativeFilePath);
        }
        else{
            log.warn("No relative path value for property 'lucene-index-base' was found in application.properties, will use the default path '{}' instead.", luceneRelativeFilePath);
            luceneAbsoluteFilePath.append(luceneRelativeFilePath);
        }
        return luceneAbsoluteFilePath.toString();
    }

I know that i can disable hibernate search completely with hibernate.search.enabled set to false but i don't want that. I want to be able to switch to lucene only without having to remove all the ElasticSearch/OpenSearch dependencies from my POM.xml beforehand. How do i do this?

EDIT: I just found out that you can set the backend type with hibernate.search.backend.type. This setting is set to the value elasticsearch by default. I should also be able to set this value to lucene but when i do that i get the following error:

    default backend: 
        failures: 
          - HSEARCH000501: Invalid value for configuration property 'hibernate.search.backend.type': 'lucene'. HSEARCH000579: Unable to resolve bean reference to type 'org.hibernate.search.engine.backend.spi.BackendFactory' and name 'lucene'. Failed to resolve bean from Hibernate Search's internal registry with exception: HSEARCH000578: No beans defined for type 'org.hibernate.search.engine.backend.spi.BackendFactory' and name 'lucene' in Hibernate Search's internal registry. Failed to resolve bean from bean manager with exception: HSEARCH000590: No configured bean manager. Failed to resolve bean from bean manager with exception: HSEARCH000591: Unable to resolve 'lucene' to a class extending 'org.hibernate.search.engine.backend.spi.BackendFactory': HSEARCH000530: Unable to load class 'lucene': Could not load requested class : lucene Failed to resolve bean using reflection with exception: HSEARCH000591: Unable to resolve 'lucene' to a class extending 
'org.hibernate.search.engine.backend.spi.BackendFactory': HSEARCH000530: Unable to load class 'lucene': Could not load requested class : lucene

EDIT 2:

I tried the setting the following settings with no success as well.

jpaProperties.put("hibernate.search.default_backend", "lucene");
jpaProperties.put("hibernate.search.backends.lucene.type", "lucene");
jpaProperties.put("hibernate.search.backend.type", "lucene");

Solution

  • You need to set the backend type explicitly according to the environment:

    jpaProperties.put("hibernate.search.backend.type", isProductionEnvironment() ? "elasticsearch" : "lucene");
    

    And you also need to have the Lucene backend in your classpath:

    <dependency>
       <groupId>org.hibernate.search</groupId>
       <artifactId>hibernate-search-backend-lucene</artifactId>
       <version>${my-hibernate-search-version}</version>
    </dependency>