Hibernate Search 6.2.0.Alpha2 is out

Posted by    |      

Hibernate Search is a library that integrates Hibernate ORM with Apache Lucene or Elasticsearch by automatically indexing entities, enabling advanced search functionality: full-text, geospatial, aggregations and more. For more information, see Hibernate Search on hibernate.org.

We just published Hibernate Search 6.2.0.Alpha2, an alpha release of the next minor version of Hibernate Search.

This version brings simpler and/or/not predicates, mass indexing for multiple tenants, and a switch to UUIDs for identifiers in the outbox-polling coordination strategy.

6.2.0.Alpha2 also includes many bugfixes and improvements, compatibility with Elasticsearch 8.6 and OpenSearch 2.5, an upgrade of -orm6 artifacts to Hibernate ORM 6.2.0.CR2, and more.

What’s new

Hibernate Search 6.2 is still in development: some features are still incomplete or may change in a backward-incompatible way.

Dependency upgrades

Hibernate ORM (HSEARCH-4747/HSEARCH-4791)

Hibernate Search now depends on Hibernate ORM 5.6.14.Final, or Hibernate ORM 6.2.0.CR2 for -orm6 artifacts.

Elasticsearch (HSEARCH-4777)

The Elasticsearch backend now works with Elasticsearch 8.6 as well as other versions that were already compatible.

OpenSearch (HSEARCH-4790)

The Elasticsearch backend now works with OpenSearch 2.5 as well as other versions that were already compatible.

Others

Standalone POJO Mapper

The Standalone POJO Mapper enables mapping arbitrary POJOs to indexes, even without Hibernate ORM. See this section of the reference documentation for more information, or this getting started guide.

In this release, there were several improvements to the configuration of the Standalone POJO mapper:

  • HSEARCH-4615: More configuration is set simply through configuration properties.

  • HSEARCH-4620: Indexing plan synchronization is now configured through strategies, just like with the ORM mapper.

Mapping index content to custom types (projection constructors)

In a previous release, Hibernate Search 6.2 introduced the ability to define projections through the mapping of custom types (typically records), by applying the @ProjectionConstructor annotation to those types or their constructor. See this section of the reference documentation for more information.

In this release, there were several improvements to the projection constructors:

  • HSEARCH-4579: With the Standalone POJO Mapper, when searching on an entity type with no loading configured, Hibernate Search will now attempt to use that entity type’s projection constructor if it exists.

  • HSEARCH-4591: Object projections are now allowed on single-valued, flattened object fields with the Lucene backend.

  • HSEARCH-4669: Hibernate Search will provide more information when a projection constructor cannot be applied to an index.

  • HSEARCH-4673: The -parameters compiler flag is no longer necessary when using the default constructor of records as projection constructor.

Mapping improvements

  • HSEARCH-4714: Property names in the mapping, e.g. @IndexingDependency(derivedFrom = …​), will now be checked early to provide a clear error message in case of incorrect syntax.

  • HSEARCH-4782: Hibernate Search will now infer a default decimal scale automatically for identifiers of Hibernate ORM entities; previously it was only inferred for non-identifier properties.

Search DSL improvements

Simpler boolean operators with the and/or/not predicates (HSEARCH-4601/HSEARCH-4645)

For simpler use cases, you can now avoid the rather complex bool predicate and use the new and/or/not predicates instead:

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.and(
                        f.match().field( "title" )
                                .matching( "robot" ),
                        f.match().field( "description" )
                                .matching( "crime" )
        ) )
        .fetchHits( 20 );
List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.or(
                        f.match().field( "title" )
                                .matching( "robot" ),
                        f.match().field( "description" )
                                .matching( "investigation" )
        ) )
        .fetchHits( 20 );
List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.not(
                f.match()
                        .field( "genre" )
                        .matching( Genre.SCIENCE_FICTION )
        ) )
        .fetchHits( 20 );
Simpler and predicate for where( (f, b) → …​ ) (HSEARCH-4676)

Instead of a bool predicate` as in 6.2.0.Alpha1, where( (f, b) → …​ ) now provides a simpler and predicate:

MySearchParameters searchParameters = getSearchParameters();
List<Book> hits = searchSession.search( Book.class )
        .where( (f, root) -> {
            root.add( f.matchAll() );
            if ( searchParameters.getGenreFilter() != null ) {
                root.add( f.match().field( "genre" )
                        .matching( searchParameters.getGenreFilter() ) );
            }
            if ( searchParameters.getFullTextFilter() != null ) {
                root.add( f.match().fields( "title", "description" )
                        .matching( searchParameters.getFullTextFilter() ) );
            }
            if ( searchParameters.getPageCountMaxFilter() != null ) {
                root.add( f.range().field( "pageCount" )
                        .atMost( searchParameters.getPageCountMaxFilter() ) );
            }
        } )
        .fetchHits( 20 );
Simpler and predicate for the nested predicate (HSEARCH-4676)

Instead of a bool predicate` as in as in 6.2.0.Alpha1 6.2.0.Alpha1, f.nested( …​ ) now provides a simpler and predicate:

List<Book> hits = searchSession.search( Book.class )
        .where( f -> f.nested( "authors" )
                .add( f.match().field( "authors.firstName" )
                        .matching( "isaac" ) )
                .add( f.match().field( "authors.lastName" )
                        .matching( "asimov" ) ) )
        .fetchHits( 20 );

Mass indexing improvements

Mass indexing multiple tenants (HSEARCH-4321)

In multi-tenant applications, mass indexing can now handle multiple tenants at once, provided you don’t pass any tenant identifier when creating the mass indexer, and you provided a list of tenants in the Hibernate Search configuration. See this section of the reference documentation for more information.

Setting up thread locals during mass indexing (HSEARCH-1809)

The mass indexer now has a concept of "mass indexing environment", allowing for instance to set up custom thread locals in mass indexing threads. See the environment parameter in this section of the reference documentation for more information.

Better exception handling (HSEARCH-4541)

Exceptions thrown by Hibernate ORM during mass indexing are now passed to the failure handler as every other exception, instead of aborting the whole mass indexing.

Smarter defaults for parameters (HSEARCH-4612)

purgeAllOnStart is now disabled by default in the mass indexer when dropAndCreateSchemaOnStart is enabled.

outbox-polling coordination improvements

Outbox events and agents now use UUIDs for their identifiers (HSEARCH-4678/HSEARCH-4748)

The primary key of the relevant tables are now using UUIDs instead of longs, to avoid reliance on sequences that were slowing down event processing on some databases. The migration guide includes migration scripts for the necessary database schema changes. See this section of the reference documentation for more information.

Other improvements and bug fixes

  • HSEARCH-4618: BooleanPredicateOptionsCollector/SimpleBooleanPredicateClausesCollector now expose a hasClause() method.

  • HSEARCH-4294: The Search DSL now allows targeting "implicit" Elasticsearch fields such as _index.

  • HSEARCH-4644: Hibernate Search is now tested regularly against CockroachDB.

  • HSEARCH-4679: Hibernate Search will now automatically simplify boolean predicates with a single clause.

  • HSEARCH-4305, HSEARCH-4708: Automatic reindexing will no longer be skipped when changing a property annotated with @OneToOne(mappedBy = …​) @IndexedEmbedded

  • HSEARCH-4727: With outbox-polling coordination and when using DB2, OutboxEvent table used to be created with a payload column with the wrong type blob(255), making it almost unusable. It is no longer the case.

  • HSEARCH-4634, HSEARCH-4647: outbox-polling coordination now works with CockroachDB.

  • HSEARCH-4652: Schema validation with the Elasticsearch backend will no longer fail when setting searchAnalyzer to the same value as analyzer on a full-text field.

  • HSEARCH-4654: Hibernate Search will no longer deadlock when experiencing a large number of concurrent failures during startup or schema validation.

  • HSEARCH-4701: When running Hibernate Search as a Java module (in the modulepath), Elasticsearch schema management will no longer lead to exceptions caused by missing inter-module dependencies.

  • HSEARCH-4703: Fixed missing entries in the Java module descriptor of hibernate-search-mapper-orm-coordination-outbox-polling leading to errors when running Hibernate Search in the modulepath.

  • HSEARCH-4724: Classpath scanning (for projection constructors in particular) no longer ignores classes within Spring Boot’s "repackaged" JARs.

And more. For a full list of changes since the previous releases, please see the release notes.

How to get this release

All details are available and up to date on the dedicated page on hibernate.org.

Getting started, migrating

For new applications, refer to the getting started guide:

For existing applications, Hibernate Search 6.2 is a drop-in replacement for 6.1, assuming you also upgrade the dependencies. Information about deprecated configuration and API is included in the migration guide.

Feedback, issues, ideas?

To get in touch, use the following channels:


Back to top