Search code examples
spring-bootspring-data-jpahibernate-searchhibernate-search-6

HibernateSearch Update Schema, drop and recreate index with Spring boot on Kubernetes cluster


I have a spring boot application that is integrated with Hibernate Search 6.0.2.Final and Elasticsearch.

When my application starts up for the first time, I have to create the indexes in ElasticSearch. Since my application will run on multiple pods, I believe, I cannot use the MassIndexer, since it will run on every node during application startup.

Secondly, after the schema and indexes are created in Elasticsearch, let's say if I add another field to the Entity class, then I will have to update the schema, and drop-recreate the indexes.

It looks like the schema management and drop-recreate of indexes should be done outside of the spring boot application. How can I achieve this using Hibernate Search Schema and Index management?


Solution

  • Schema updates and mass indexing should, indeed, happen from a single node.

    First, you need to disable automatic schema management on startup:

    hibernate.search.schema_management.strategy = none
    

    Then, you need an administration interface in your application (that only maintainers have access to), with a button that will trigger schema updates and mass indexing. Alternatively this can be a simple authenticated REST endpoint if you'd rather do this through scripts.

    With such a button or endpoint, you can:

    • Spin up your application nodes.
    • Then press the button on the administration console to trigger the schema update and mass indexing, which will happen on one node only.

    Alternatively, if for some reason you don't want to expose mass indexing through your application, you can probably use a CommandLineRunner or ApplicationRunner that only performs stuff when you start the application with a particular argument (e.g. mass-index). That way you just start your application somewhere with the argument that triggers mass indexing, wait for mass indexing to end, stop the application, and only then do the actual deployment. I'm not a Spring expert though, so I'll let you search the web for how to use CommandLineRunner/ApplicationRunner.