Hello again. Firstly i use the version 6.1.8.Final.
Βecause I manage processes with a large volume of data, I have disabled the automatic indexes → hibernate.search.automatic_indexing.strategy=none.
So I have set a boolean skipIndexing, by default false, and when I run the above complex processes I change its value to true.
I use a Listener where depending on the value of skipIndexing, I update or not the indexes.
public class MyListener {
@PostUpdate
@PostPersist
public void post(final Object object) {
final boolean skip = object instanceof MyBaseEntity && ((MyBaseEntity) object).isSkipIndexing();
if (skip) {
final IndexingService indexingService = ApplicationContextHolder.applicationContext.getBean(IndexingService.class);
indexingService.indexObjectManually(object, true);
}
}
@PostRemove
public void remove(final Object object) {
final boolean skip = object instanceof MyBaseEntity && ((MyBaseEntity) object).isSkipIndexing();
if (!skip) {
final IndexingService indexingService = ApplicationContextHolder.applicationContext.getBean(MyService.class);
indexingService.indexObjectManually(object, false);
}
}
}
My object:
@Indexed(index = "...")
@Table(name = "...")
public class MyObject extends MyBaseEntity {
@Id
@Column(name = "id", nullable = false, precision = 18)
@ScaledNumberField(decimalScale = 0, sortable = Sortable.YES)
private BigInteger id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "objectBId", nullable = false)
@IndexedEmbedded(includePaths = {"id", "field1", "field2"})
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
private MyObjectB objectB;
.
.
.
}
I have a process that I have to manage a large volume of data
for (final MyObject object : myObjectList) {
object.setSkipIndexing(true);
}
final int batchSize = 1000;
for (int i = 0; i < myObjectList.size(); i += batchSize) {
final List<YdrTran> batchList = myObjectList.subList(i, Math.min(i + batchSize, ydrTranList.size()));
ydrTranRepository.saveAllAndFlush(myObjectList);
System.out.println(i + batchSize);
try {
final Set<BigInteger> ids = batchList.stream().map(MyObject::getId).collect(Collectors.toSet());
indexingService.indexingByClassAndCondition(MyObject.class, ids);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
MyService
public void indexObjectManually(final Object object, final boolean isUpdate) {
if (AnnotationChecker.hasAnnotation(object.getClass(), Indexed.class)) {
final SearchSession searchSession = Search.session(em);
final SearchIndexingPlan indexingPlan = searchSession.indexingPlan();
if (isUpdate) {
indexingPlan.addOrUpdate(object);
} else {
indexingPlan.delete(object);
}
}
}
public void indexingByClassAndCondition(final Class<?> clazz, final Set<BigInteger> conditionIds) throws InterruptedException {
final SearchSession searchSession = Search.session(em);
final MassIndexer massIndexer = searchSession.massIndexer(clazz);
massIndexer
.purgeAllOnStart(false)
.type(clazz)
.reindexOnly("id in ( " + ":ids" + ")")
.param("ids", conditionIds);
massIndexer.startAndWait();
em.clear();
}
Τhe result is that new indexes are updated for the specific ids but the previous ones are not deleted, resulting in duplicates. How can i avoid this ?
Thank you !