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 8.0.0.Alpha1, the first alpha release of the next major version of Hibernate Search.

This version brings metric aggregations, logging improvements, a new Lucene backend and more.

Hibernate Search 8.0 sets JDK 17 as a baseline and is no longer compatible with JDK 11.

It also upgrades Lucene and Hibernate ORM dependencies and includes compatibility with the latest Elasticsearch and OpenSearch versions.

What’s new

Hibernate Search 8.0 is still in its early stages of development: some features still need to be completed or may change in a backwards-incompatible way.

Dependency upgrades

JDK (HSEARCH-48514)

Hibernate Search upgrades to JDK 17 as the baseline and drops JDK 11 compatibility.

Hibernate ORM (HSEARCH-5284)

Hibernate Search now targets the Hibernate ORM 7.0 series, which implements Jakarta Persistence 3.2.0. In particular, it is currently based on Hibernate ORM 7.0.0.Beta3.

Lucene (HSEARCH-5292)

The Lucene backend now uses Lucene 9.12.1.

Elasticsearch (HSEARCH-5269/HSEARCH-5289)

The Elasticsearch backend is compatible with Elasticsearch 8.16 and 8.17, as well as other already compatible versions.

OpenSearch (HSEARCH-5245/HSEARCH-5266)

The Elasticsearch backend works with OpenSearch 2.17 and 2.18, as well as other already compatible versions.

Others

Metric aggregations

The Hibernate Search DSL now allows requesting metric aggregations:

AggregationKey<Double> avgPriceKey = AggregationKey.of( "avgPrice" ); (1)
AggregationKey<LocalDate> oldestReleaseKey = AggregationKey.of( "oldestRelease" ); (2)

SearchResult<Book> result = searchSession.search( Book.class )
    .where( f -> f.matchAll() )
    .aggregation( avgPriceKey, f -> f.avg().field( "price", Double.class ) ) (3)
    .aggregation( oldestReleaseKey, f -> f.min().field( "releaseDate", LocalDate.class ) ) (4)
    .fetch( 20 );

Double avgPrice = result.aggregation( avgPriceKey ); (5)
LocalDate oldestRelease = result.aggregation( oldestReleaseKey );
1 Create an aggregation key for an average price aggregation.
2 Create an aggregation key for a minimum date aggregation.
3 Request an .avg() aggregation on the price field. Specifying Double here defines the expected return type of the computed aggregation.
4 Request a .min() aggregation on the release date field. Specifying LocalDate here defines the expected return type of the computed aggregation.
5 Extract the aggregated value from the results.

See the corresponding section on metric aggregations to learn which aggregations are available.

New Lucene backend

While Hibernate Search 8.0 still targets JDK 17, Lucene, starting with version 10, is leveraging new Java APIs, particularly to work with memory, that are available starting with JDK 21. To give users an option to work with the newer Lucene version, Hibernate Search introduces the hibernate-search-backend-lucene-next backend.

Currently, this backend is backed by Lucene 10 and requires JDK 21. In terms of functionality, both Lucene-based backends have the same search capabilities.

See this section of the reference documentation to learn more.

Projecting multivalued fields

It is now possible to use other collection types than List for multivalued projections:

Example 1. Using a Set to collect author names in a projection constructor
@ProjectionConstructor
public record MyBookProjection(
    @IdProjection Integer id,
    String title,
    Set<String> authors) {  (1)
}
1 Using Set as a collection for a multivalued projection.
Example 2. Using the set collector within projection DSL
List<Set<String>> hits = searchSession.search( Book.class )
    .select( f -> f.field( "authors.lastName", String.class ).set() ) (1)
    .where( f -> f.matchAll() )
    .fetchHits( 20 );
1 Using the set collector.

Hibernate Search comes with implementation for most popular collections, but it is also possible to extend it and use a custom collector for an unsupported collection:

List<MyCustomCollection<String>> hits = searchSession.search( Book.class )
    .select( f -> f.field( "authors.lastName", String.class ).collector( new MyCustomCollector() ) ) (1)
    .where( f -> f.matchAll() )
    .fetchHits( 20 );
1 Pass an instance of ProjectionCollector.Provider to the .collector() method.

Logging categories

Hibernate Search now utilizes logging categories instead of FQCNs. It is now easier to enable logging when debugging a particular area of Hibernate Search:

# Set logging level for massindexing events to `TRACE`:
org.hibernate.search.mapper.massindexing=TRACE

See the corresponding section on logging categories to find out which categories are available.

Other improvements and bug fixes

  • HSEARCH-5208: Add a fail-fast configuration option to the mass indexer.

  • HSEARCH-5180: Better mass indexing support for data streams with an initially unknown total size

  • HSEARCH-2945: Update the massindexer monitor API and the default logging implementation.

And more. Please see the release notes for a complete list of changes since the previous releases.

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 8.0 is a drop-in replacement for 7.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