| I think there's actually a bug in Hibernate Search, which previously was hidden in our test case due to the unnecessary initializations in Hibernate ORM. The currently failing test (CollectionUpdateEventTest.testWithClassBridge) sets up this chain of associations:
And assumes (though it's far from explicit) this chain of dependency from the point of view of index content:
These "contained in" relationships are due to both the presence of @IndexedEmbedded annotations, and more importantly to the the presence of a class bridge on Item, which could theoretically use about anything in Catalog. Hence, modifying anything in Catalog should result in the associated Item instances to be reindexed: we simply don't know which data the class bridge depends on. The thing is, due to
HSEARCH-782 Closed we have an "optimization" in place that will make us skip reindexing when the collection being modified wasn't initialized. This can happen when simply adding an element to an uninitialized collection, for instance: the added element is simply added to a queue under the hood (see org.hibernate.collection.internal.PersistentBag.add(Object)). The
HSEARCH-782 Closed optimization is located in FullTextIndexEventListener:
protected void processCollectionEvent(AbstractCollectionEvent event) {
PersistentCollection persistentCollection = event.getCollection();
final String collectionRole;
if ( persistentCollection != null ) {
if ( !persistentCollection.wasInitialized() ) {
return;
}
collectionRole = persistentCollection.getRole();
}
}
But this optimization is, in my opinion, pure nonsense: additions to the collection could totally affect other indexes containing the collection owner. This is true in our case, where Item has a class bridge which could depend on practically anything, but it's also true without a class bridge. See for instance this mapping:
public class Catalog {
@ContainedIn
@OneToMany(mappedBy = "catalog", cascade = { CascadeType.REMOVE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
private Set<CatalogItem> catalogItems = new HashSet<CatalogItem>();
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "catalogs", cascade = { CascadeType.PERSIST })
@Field(bridge = @FieldBridge(impl = SomeBridge.class))
private List<Consumer> consumers = new ArrayList<Consumer>();
}
Adding a consumer would keep the consumer list uninitialized, but would obviously still affect the index of catalog items, since there is a field bridge on "consumers". I'm currently investigating
HSEARCH-782 Closed to see if we could fix it another way... But I suspect there's a bug here, which may affect Hibernate Search even without the Hibernate ORM upgrade. I'll open another ticket if necessary. |