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 ! 