Home > Enterprise >  Using Hibernate Search 6 - How to prevent automatic indexing for a specific entity?
Using Hibernate Search 6 - How to prevent automatic indexing for a specific entity?

Time:10-13

We would like to handle the indexing ourselves for one of our Hibernate Search entities.

Is it possible to disable auto indexing within Hibernate Search 6 for a specific entity? Similar to the older Hibernate Search global setting: hibernate.search.indexing_strategy = manual

I've searched through the documentation but haven't seen this mentioned.

CodePudding user response:

hibernate.search.indexing_strategy = manual was for all entity types, not for a specific one.

The feature you're looking for has already been filed as HSEARCH-168, and is currently planned for Hibernate Search 6.2.

In the meantime, I think the best you can do would be to rely on a hack. It won't be as efficient as what we envision for HSEARCH-168, but it's a start:

  • Implement a RoutingBridge which, based on a switch, will either disable indexing completely (both adding and removing the entity from the index) or behave normally as if there was no routing bridge:
    public class ManualIndexingRoutingBinder implements RoutingBinder {
    
        private static volatile boolean indexingEnabled = false;
    
        public static synchronized void withIndexingEnabled(Runnable runnable) {
            indexingEnabled = true;
            try {
                runnable.run();
            }
            finally {
                indexingEnabled = false;
            }
        }
    
        @Override
        public void bind(RoutingBindingContext context) { 
            context.dependencies() 
                    .useRootOnly();
    
            context.bridge( 
                    Book.class, 
                    new Bridge() 
            );
        }
    
        public static class Bridge implements RoutingBridge<Book> { 
            @Override
            public void route(DocumentRoutes routes, Object entityIdentifier, Book indexedEntity, 
                    RoutingBridgeRouteContext context) {
                if ( indexingEnabled ) { 
                    routes.addRoute();
                }
                else {
                    routes.notIndexed(); 
                }
            }
    
            @Override
            public void previousRoutes(DocumentRoutes routes, Object entityIdentifier, Book indexedEntity, 
                    RoutingBridgeRouteContext context) {
                if ( indexingEnabled ) {
                    // So that Hibernate Search will correctly delete entities if necessary.
                    // Only useful if you use SearchIndexingPlan for manual indexing,
                    // as the MassIndexer never deletes documents.
                    routes.addRoute();
                }
                else {
                    routes.notIndexed(); 
                }
            }
        }
    }
    
  • Apply that routing bridge to the entity types you want to control:
    @Entity
    @Indexed(routingBinder = @RoutingBinderRef(type = ManualIndexingRoutingBinder.class))
    public class Book {
        // ...
    }
    
  • The routing bridge will effectively disable automatic indexing.
  • To index manually, do this:
    ManualIndexingRoutingBinder.withIndexingEnabled(() -> {
        Search.mapping(entityManagerFactory).scope(Book.class)
                .massIndexer()
                .startAndWait();
    });
    

I didn't test this exactly, so please report back, but in principle this should work.

  • Related