In this circumstance,
When indexing failed for the reason such as elasticsearch server down, time out etc,
i want to invoke implemented FailureHandler with write-sync setting (automatic_indexing.synchronization.strategy).
Because it is easy to recovery failed indexing data using FailureHandler(especially EntityIndexingFailureContext argument handle method).
package com.mycompany;
import ...;
public final class MyWriteSyncAutomaticIndexingSynchronizationStrategy
implements AutomaticIndexingSynchronizationStrategy {
public static final MyWriteSyncAutomaticIndexingSynchronizationStrategy INSTANCE = new MyWriteSyncAutomaticIndexingSynchronizationStrategy();
private MyWriteSyncAutomaticIndexingSynchronizationStrategy() {
}
@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( throwable );
contextBuilder.failingOperation( "automatic indexing" );
for ( EntityReference entityReference : result.failingEntities() ) {
contextBuilder.entityReference( entityReference );
}
failureHandler.handle( contextBuilder.build() );
} );
} );
}
}
Make sure youâre using version 6.0.0.CR2.
Then set configuration property hibernate.search.automatic_indexing.synchronization.strategy to constructor:com.mycompany.MyWriteSyncAutomaticIndexingSynchronizationStrategy.
And i intent to use EntityManager code in FailureHandler (bean registered) like below
@Component(value = "myFailureHandler")
public class MyFailureHandler implements FailureHandler {
...
@PersistenceContext
private EntityManager entityManager;
...
}
In this case, there are some issues,
When background_failure_handler declared start with bean:,
error occured like this org.hibernate.search.util.common.SearchException: HSEARCH000501: Invalid value for configuration property âhibernate.search.background_failure_handlerâ: âbean:myFailureHandlerâ. HSEARCH000579: Unable to resolve bean reference to type âorg.hibernate.search.engine.reporting.FailureHandlerâ and name âmyFailureHandlerâ. Failed to resolve bean from bean manager with exception: HSEARCH000590: No configured bean manager.
When background_failure_handler declared start with class: or constructor:, EntityManager dependency injection in MyFailureHandler not effected, so that is null
In this situation, Is there a good way the hibernate search provides?
There is no built-in solution for what youâre trying to achieve, no.
Regarding the injection of an entity manager into the failure handler, thatâs probably not a good idea, since the failure handler is instantiated while the entity manager factory is being built, so it canât be used at this time.
If you really want to do something like this, you will have to implement a dedicated Spring component that performs whatever you want to do with the entity manager, and inject that service into your failure handler with @Lazy @Autowired. See https://www.baeldung.com/spring-lazy-annotation
I have the same condition here however i am trying to inject hazelcast instance so as to cache failing entities to try index them later; Can you please give us more details about how we could achieve this?