[JIRA] (HSEARCH-3857) Avoid ConcurrentModificationException when indexing multiple entities with addOrUpdate wich contains @IndexEmbedded dependencies
by Alexis CUCUMEL (JIRA)
Alexis CUCUMEL ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *updated* an issue
Hibernate Search ( https://hibernate.atlassian.net/browse/HSEARCH?atlOrigin=eyJpIjoiYTNkZGY2... ) / Bug ( https://hibernate.atlassian.net/browse/HSEARCH-3857?atlOrigin=eyJpIjoiYTN... ) HSEARCH-3857 ( https://hibernate.atlassian.net/browse/HSEARCH-3857?atlOrigin=eyJpIjoiYTN... ) Avoid ConcurrentModificationException when indexing multiple entities with addOrUpdate wich contains @IndexEmbedded dependencies ( https://hibernate.atlassian.net/browse/HSEARCH-3857?atlOrigin=eyJpIjoiYTN... )
Change By: Alexis CUCUMEL ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
In some cases the SearchIndexingPlan generate a ConcurrentModificiationException if an embedded entities is not listed in the *addOrUpdate* or on specific order (if only the *last* entity is concern this case)
{noformat}SearchSession searchSession = Search.session((EntityManager) sessionFactory.getCurrentSession());
SearchIndexingPlan searchWritePlan = searchSession.indexingPlan();
// this order endup to the exception below
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class), 12445l));
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class, 12444l));
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class, 12443l));
// this order is fine
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class), 12443l));
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class, 12444l));
searchWritePlan.addOrUpdate(rootRepository.load(ClientPhysique.class, 12445l));
searchWritePlan.process();
searchWritePlan.execute();
{noformat}
Explanation from *@**yrodiere* *:*
The problem is probably in {{ org.hibernate.search.mapper.pojo.work.impl.PojoIndexingPlanImpl#process }} , in this loop:
{noformat} for ( PojoIndexedTypeIndexingPlan<?, ?, ?> delegate : indexedTypeDelegates.values() ) {
delegate.resolveDirty( this::updateBecauseOfContained );
}
{noformat}
The call to {{ resolveDirty }} will trigger a loop on {{ indexingPlansPerId }} that executes an operation of each element of that map.
The problem is, this operation might trigger the addition of an element to the map {{ indexedTypeDelegates }} (through {{ org.hibernate.search.mapper.pojo.work.impl.PojoIndexingPlanImpl#getOrCreateIndexedDelegateForContainedUpdate }} ), or to the map {{ indexingPlansPerId }} (through {{ org.hibernate.search.mapper.pojo.work.impl.PojoIndexedTypeIndexingPlan#getPlan }} ), when we discover a type/entity that wasn’t present in the map initially.
The concurrent modification is not a problem _per se_, because we don’t need to call {{ resolveDirty }} on newly added elements. However, it’s a problem because the iterator will detect the concurrent modification and throw an exception.
see [https://discourse.hibernate.org/t/searchindexingplan-exception-when-using...]
( https://hibernate.atlassian.net/browse/HSEARCH-3857#add-comment?atlOrigin... ) Add Comment ( https://hibernate.atlassian.net/browse/HSEARCH-3857#add-comment?atlOrigin... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100121- sha1:b4d24b6 )
4 years, 9 months