Hibernate Search 6.0.0.Alpha3 released!

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.0.0.Alpha3, the third release for the still-in-development 6.0 branch. This release mainly adds support for more field types and predicates, and brings more consistent and less verbose APIs.

Getting started with Hibernate Search 6

If you want to dive right into the new, shiny Hibernate Search 6, a good starting point is the getting started guide included in the reference documentation.

Hibernate Search 6 is still in development and its APIs differ significantly from Search 5.

For more information about the current status of this branch, see the page dedicated to Search 6 on hibernate.org.

For more information about migration and what we intend to do to help you, see the migration guide.

What’s new

It’s been a long time since the last release. But this also means we’ve made a lot of progress!

Quarkus integration

You may have heard of Quarkus, a framework and toolset aiming at dramatically improving the boot time and memory usage of Java applications.

We’ve been working on integrating Hibernate Search into Quarkus, and an experimental Quarkus Extension should be released soon. Stay tuned!

Most basic Java types can now be indexed

In HSEARCH-3047 and HSEARCH-3503, we restored the ability to index most basic Java types.

The following types are now supported:

  • java.lang.String

  • java.lang.Character, char

  • java.lang.Byte, byte

  • java.lang.Short, short

  • java.lang.Integer, int

  • java.lang.Long, long

  • java.lang.Double, double

  • java.lang.Float, float

  • java.lang.Boolean, boolean

  • java.net.URI

  • java.net.URL

  • java.time.Instant

  • java.time.LocalDate

  • java.time.LocalTime

  • java.time.LocalDateTime

  • java.time.OffsetDateTime

  • java.time.OffsetTime

  • java.time.ZonedDateTime

  • java.time.ZoneId

  • java.time.ZoneOffset

  • java.time.Period

  • java.time.Duration

  • java.time.Year

  • java.time.YearMonth

  • java.time.MonthDay

  • java.util.UUID

  • java.util.Calendar

  • java.util.Date

  • java.sql.Timestamp

  • java.sql.Date

  • java.sql.Time

The only notable types that aren’t supported yet are BigDecimal and BigInteger.

See the documentation for more information:

Most search predicates are now implemented

In Alpha2, only some of the search predicates were implemented:

  • matchAll

  • id

  • bool

  • match

  • range

  • nested

  • spatial "within" (distance)

In HSEARCH-3091 and HSEARCH-3256, we made sure that most predicate options available in Search 5 are available in Search 6 (only the analyzer override is missing).

In HSEARCH-3089, we implemented the following predicates:

  • phrase

  • wildcard

  • simpleQueryString

Bringing us almost on par with Search 5, with only facet and moreLikeThis missing.

Unified, more straightforward APIs

We’ve been hard at work to make the change of APIs in Search 6 really worth it.

The previous releases made sure that APIs were more powerful, allowing in particular to safely create predicates targeting multiple indexes, or to create type-safe queries.

In this release, we ensured that the names were more consistent, more straightforward and less verbose than in Search 5.

Below is a query as you would write it in Search 5.

FullTextSession ftSession = Search.getFullTextSession(session);
QueryBuilder bookQb = ftSession.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get();
QueryBuilder dvdQb = ftSession.getSearchFactory().buildQueryBuilder().forEntity(Dvd.class).get();

// Find all long documents: books with more than 500 pages or dvd lasting more than 2 hours
Query luceneQuery = bookQb.bool()
    .should(bookQb.range().onField("pageCount").above(500).createQuery())
    .should(dvdQb.range().onField("durationInMinutes").above(120).createQuery())
    .createQuery();

FullTextQuery query = ftSession.createFullTextQuery(luceneQuery, Book.class, Dvd.class);

query.setMaxResults(pageSize).setFirstResult(selectedPage*pageSize); // Pagination

@SuppressWarnings("unchecked")
List<Document> results = query.list();

Below is an equivalent query in Search 6 Alpha1/Alpha2: no more per-type query builders, no more "lucene query", no more dodgy raw types that must be casted.

FullTextSession ftSession = Search.getFullTextSession(session);

FullTextQuery<Document> query = ftSession.search(Arrays.asList(Book.class, Dvd.class)).query().asEntity()
    .predicate(f -> f.bool()
        .should(f.range().onField("pageCount").above(500))
        .should(f.range().onField("durationInMinutes").above(120))
        .toPredicate()
    )
    .build();

query.setMaxResults(pageSize).setFirstResult(selectedPage*pageSize); // Pagination

List<Document> results = query.list();

And below is an equivalent query in Search 6 Alpha3: no more meaningless query() or toPredicate() calls, a unified naming for all types (prefixed with Search) and a unified method name to retrieve results (fetch, fetchHits, fetchCount, …​)

SearchSession searchSession = Search.getSearchSession(session);

SearchQuery<Document> query = searchSession.search(Arrays.asList(Book.class, Dvd.class)).asEntity()
    .predicate(f -> f.bool()
        .should(f.range().onField("pageCount").above(500))
        .should(f.range().onField("durationInMinutes").above(120))
    )
    .toQuery();

List<Document> results = query.fetchHits(pageSize, selectedPage*pageSize);

For details, see:

  • HSEARCH-3444: Reduce the verbosity of the predicate/projection/sort DSLs and index schema DSL

  • HSEARCH-3403: Remove the inheritance from FullTextQuery/FullTextSession to the corresponding Hibernate ORM types

  • HSEARCH-3498: Move optional predicate DSL parameters to the terminal contexts

  • HSEARCH-3511: Make the entry points to the Search API more intuitive

We also changed the syntax for adding values to documents in bridges: see HSEARCH-3295.

And finally, we made the names of configuration properties more consistent between the Elasticsearch and Lucene backend: HSEARCH-3482.

Documentation

The documentation is still sparse, but it continues to grow. We documented in particular the configuration properties (HSEARCH-3473, see here) and the limitations of using the date/time types from java.util (HSEARCH-3509, see here).

Version upgrades

  • HSEARCH-3483: Upgrade to Lucene 7.7.0

  • HSEARCH-3520: Upgrade to Elasticsearch 6.6.2

  • HSEARCH-3490: There is now experimental support for Elasticsearch 7.0.0-beta1.

  • HSEARCH-3514: We restored automatic Java module names to our JARs, which can thus be safely referenced from your module-info.java.

    ADDENDUM (2019-04-05): it turns out there are still problems with using Hibernate Search from Java modules. See HSEARCH-3551.

  • HSEARCH-3485, HSEARCH-3493: Hibernate Search still targets JDK8 and JDK11, but now we also test compatibility with JDK12 and JDK13 regularly.

Other improvements and bug fixes

  • HSEARCH-3424: The showcase module now uses Spring Boot, for a more realistic example of how to use Hibernate Search in an application. See the code on GitHub.

  • HSEARCH-3257: Allow to bypass bridges in projections

  • HSEARCH-2658: Support @Inject in all user-provided components: bridges, configurers, …​

  • HSEARCH-1640: boolean field should never be analyzed

  • HSEARCH-2908: Incorrect mapping for 'java.lang.Short and java.lang.Byte' fields with Elasticsearch.

  • HSEARCH-3481: Change max_connections_per_route default value to 10

  • HSEARCH-3251: Avoid "fuzzy" query in Elasticsearch and prefer "match" query with "fuzziness" parameter

  • HSEARCH-2248: Remove deprecated threshold method for fuzzy queries from the DSL

  • HSEARCH-3477: Wrong incompatible types error when query a full text field across different indexes on Lucene backend

  • HSEARCH-3489: Improve the error message when the inverse side of an association cannot be found by Hibernate Search

  • HSEARCH-3529: MassIndexer fails for entities with primitive ID type

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.

Feedback, issues, ideas?

To get in touch, use the following channels:


Back to top