Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Main issue: #5701
Summary
Lets a module contribute Search index definitions derived from runtime metadata, and makes Search's indexing, enqueueing and change-tracking paths work for entities and properties the JPA store does not know. This is the open-source half of the Dynamic Model integration; Search itself stays independent of Dynamic Model.
What was done
IndexDefinitionContributorextension point (modulesearch, packageio.jmix.search.index.mapping) with theContributedIndexDefinitionrecord. Contributor beans are consulted every time the index configurations of a metadata generation are built. A contribution for an entity without a Java definition creates a configuration; one for an entity with a Java definition appends its fields, and fields the Java definition already maps win.DataManagerconditions instead of JPQL: the indexer's reload of instances,enqueueIndexAll, and the paged enqueueing session (newNonJpaEntityIdsLoader).DependentEntitiesLoaderno longer builds JPQL for a back-reference path that is not JPA-mapped. It loads the owners through aPropertyConditionon the reference instead. Before, the failed JPQL inside the save transaction marked it rollback-only, so saving an entity referenced through such a property failed. A path through a non-JPA collection is skipped with a warning.IndexStateRegistryreports entities of later generations as unavailable instead of unknown and ignores state changes for retired ones, and the Elasticsearch and OpenSearch index settings providers cache by entity name rather than by Java class, which changes for a dynamic entity on every generation.StartupIndexSynchronizerruns onApplicationStartedEventatJmixOrder.LOWEST_PRECEDENCEinstead of@PostConstruct, so add-ons that publish metadata on startup run first. Without that, the defaultcreate-or-recreatestrategy compared indexes against a mapping built from incomplete metadata and dropped them on each restart.search-flowui:fullTextFilterworks on a list view of a non-JPA entity by restricting the primary key to the found ids with aPropertyCondition; a search hit whose entity has no detail view shows a warning notification;SearchResultsViewpasses the identifier value rather than theIdwrapper when reloading, which only the JPA store unwrapped.How it works
IndexConfigurationManagerparses the annotated Java definitions, then merges the contributions of everyIndexDefinitionContributorbean into the same map, keyed by entity name, and registers the result for the current or pinned metadata generation. Because configurations are stored per generation, a new generation published at runtime rebuilds the merged set lazily on first use, andrefreshIndexDefinitions()includes contributions. Everywhere Search used to run JPQL against an entity or property, it first asksMetadataToolswhether the target is JPA; if not, it goes throughDataManagerwith conditions, which the entity's own store translates.How to use
Implement
IndexDefinitionContributoras a Spring bean and return oneContributedIndexDefinitionper entity, with the entity name, an optional index name and aMappingDefinitionbuilt with the existing builders. Return an empty collection when there is nothing to contribute. The definitions must describe the metadata generation that is pinned or current for the calling thread.Breaking changes
FullTextFilter.getQueryCondition()no longer overrides the base method with aJpqlConditionreturn type; the inheritedConditionis returned and may be aPropertyCondition. Code that relied on the covariant return type stops compiling.ApplicationStartedEventinstead of during bean initialization. Application code that expected indexes to be synchronized when the context is refreshed is affected.IndexStateRegistry.markIndexAsAvailable/markIndexAsUnavailableno longer throw for an entity that is not indexed; they log at debug level.Compatibility
Applications without a contributor and without non-JPA entities see the same index configurations as before. The startup order change applies to every application using Search.
Test plan
jmix-premium(:dynmodel:test), because thesearchmodule's own test context has no non-JPA store.