Failure handler doesn't work

Hi all~

I want to catch indexing failure to save failed item in RDB and reprocess it later.
But, following error happened.

HSEARCH000568: Invalid configuration passed to Hibernate Search: some properties in the given configuration are not used. There might be misspelled property keys in your configuration. Unused properties: [hibernate.search.automatic_indexing.synchronization.strategy.constructor].

What should I check?

spring hibernate search setting file is as follows.

jpa:
  properties:
      hibernate:
       search:
          schema_management:
            strategy: create
          backend:
            connection_timeout: 5000
            read_timeout: 30000
            max_connections: 20
            max_connections_per_route: 10
            layout:
              strategy: simple
            hosts: localhost:9200
            protocol: http
            dynamic_mapping: true
            schema_management:
              settings_file: config/elasticsearch-index-settings.json
            indexes:
              product:
                schema_management:
                  mapping_file: config/elasticsearch-index-mapping.json
          automatic_indexing:
            synchronization:
              strategy:
                constructor: com.company.configuration.FailureHandlingWriteSyncAutomaticIndexingSynchronizationStrategy
          background_failure_handler: com.company.application.es.EsFailureHandler

2 file in setting are as follows.

@NoArgsConstructor
public final class FailureHandlingWriteSyncAutomaticIndexingSynchronizationStrategy
        implements AutomaticIndexingSynchronizationStrategy {

    private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );

    public static final AutomaticIndexingSynchronizationStrategy INSTANCE = new FailureHandlingWriteSyncAutomaticIndexingSynchronizationStrategy();

    @Override
    public String toString() {
        return AutomaticIndexingSynchronizationStrategy.class.getSimpleName() + ".failureHandlingWriteSync()";
    }

    @Override
    public void apply(AutomaticIndexingSynchronizationConfigurationContext context) {
        context.documentCommitStrategy( DocumentCommitStrategy.FORCE );
        context.documentRefreshStrategy( DocumentRefreshStrategy.NONE );
        FailureHandler failureHandler = context.failureHandler();
        context.indexingFutureHandler( future -> {
            // Wait for the result of indexing, so that we're sure changes were committed (or failed).
            SearchIndexingPlanExecutionReport report = future.join();
            report.throwable().ifPresent( t -> {
                EntityIndexingFailureContext.Builder contextBuilder = EntityIndexingFailureContext.builder();
                contextBuilder.throwable( t );
                contextBuilder.failingOperation( log.automaticIndexing() );
                for ( EntityReference entityReference : report.failingEntities() ) {
                    contextBuilder.entityReference( entityReference );
                }
                failureHandler.handle( contextBuilder.build() );
            } );
        } );
    }
}





public class EsFailureHandler implements FailureHandler {

    private EntityManagerFactory entityManagerFactory;

    @Override
    public void handle(FailureContext context) {
        logger.error("[EsFailureHandler:FailureContext] failingOperationDescription: {}, throwable: {}", context.failingOperation(), context.throwable());
    }

    @Override
    public void handle(EntityIndexingFailureContext context) {
        logger.error("[EsFailureHandler:EntityIndexingFailureContext] failingOperationDescription: {}, throwable: {}", context.failingOperation(), context.throwable());        
    }

It’s not a failure or an error, it’s a warning. Thus it’s not handled by the failure handler.

Even if it was, the purpose of the failure handler is to handle failures at runtime; it won’t catch failures during startup, because those cannot be safely ignored nor recovered from.

The configuration property hibernate.search.automatic_indexing.synchronization.strategy.constructor does not exist. Your YAML is incorrectly formatted, and the contructor: is interpreted as part of the key instead of being part of the value.

Try this instead:

          automatic_indexing:
            synchronization:
              strategy: "constructor:com.company.configuration.FailureHandlingWriteSyncAutomaticIndexingSynchronizationStrategy"
1 Like