Your application interacts with Hibernate libraries, and those in turn interact with third-party software: JDBC drivers, other libraries, or even REST APIs (Elasticsearch/OpenSearch). When any of these components changes its API, there is a risk that it becomes incompatible. This page explains how Hibernate projects try to limit incompatible changes.
Concepts
Code categorization (API/SPI/internals/…)
We conceptually divide the classes of the codebase into 3 broad categories:
-
The Application Programming Interface (API) is the set of contracts exposed to the application. For example,
Session#save
. It is an interface for your application to interact with a Hibernate library. This is code that we fully expect to be directly linked to your application bytecode by the compiler. -
A Service Provider Interface (SPI) is an "integration point" with a Hibernate library and the contracts needed to perform those integrations. It is an interface for frameworks or third-party libraries (caching implementations, …) to integrate with a Hibernate library.
-
The internals are classes and code meant only for the Hibernate library’s usage internally.
For the most part we try to denote these distinctions through the placement of classes into packages:
-
Classes in packages with
internal
orimpl
in the name are internal. -
Classes in packages with
spi
in the name are SPI. -
Classes in packages with neither
internal
,impl
norspi
in the name are API.
For Hibernate ORM, grouping code into packages in this manner is an ongoing process and is still incomplete. The reason we could not do it en masse is, oddly, backwards compatibility. |
Additionally, some classes, methods or fields may be annotated to introduce exceptions:
-
Code annotated with
@Internal
is internal. This annotation is used for code that leaks through API or SPI due to technical constraints or for historical reasons. -
Code annotated with
@Incubating
is not part of an API or SPI yet, but may be in the future. This annotation is used for code that is still under development and may still change incompatibly.
Versioning scheme
Hibernate projects are versioned according to the following scheme:
major.minor.micro.qualifier
Where:
-
major
,minor
andmicro
are incrementing integers. -
qualifier
isAlpha1
,Alpha2
, etc.,Beta1
,Beta2
, etc., for development releases,CR1
,CR2
, etc. for candidate releases orFinal
for stable releases.
For example: 4.0.0.Final
, 5.2.0.Beta2
, 5.4.0.CR1
.
For the most part we follow the guidelines as defined by JBoss Project Versioning Guidelines, so that is a good background material.
Hibernate, however, applies some additional semantics. Roughly speaking:
-
Major updates imply potentially incompatible changes to existing APIs. This may include removal of some APIs.
-
Minor updates are simply additions to existing APIs.
-
Micro updates are for bugfixes only.
-
Alpha/Beta updates are for work in progress and may change newly introduced APIs.
Details can be found further down in Compatibility between applications and Hibernate projects.
Compatibility between applications and Hibernate projects
This section discusses the expectations users should have regarding compatibility between their application and Hibernate projects.
The principles below are guidelines. While we strive to follow them as much as possible, there are times when exceptions need to be made. For example, if the design of a small part of the API renders it useless or causes critical bugs, we may decide to change it incompatibly in a bugfix (micro) release. Another exception is when backporting support for standards. We might decide to introduce "transition" minors that upgrade to a newer version of a standard while keeping backward compatibility everywhere else, in order to ease the migration to the next major version. For example Hibernate ORM 5.5 might upgrade to Jakarta 9’s persistence API (and change nothing else) to ease the migration to Hibernate ORM 6.0. |
API
API contracts are stable across all releases within a major version.
For example, if you develop an application initially using Hibernate ORM version 4.0.0 and the application only relies on the defined APIs, the expectation is that you can drop in any newer Hibernate 4.x version and it will JustWork.
This is what is called backwards compatibility: any changes done in 4.3 (for example) are done in such a way as to remain compatible with older (backward) versions all the way back to 4.0.
The inverse is something we actually do not guarantee in regards to APIs and going back to an older version (reverting). An example here would be developing an application using the natural-id API developed in 4.2 and then trying to drop Hibernate ORM 4.1 or 4.0 into that application. That won’t work.
So within a major version we guarantee APIs to be backwards compatible, but not forward compatible. Newer releases might add to an API, but they should not alter or remove.
SPI
SPI contracts are stable across all releases within a minor version, but not necessarily across different minors of the same major.
For example, an integration developed against Hibernate ORM 4.0.0 will work with 4.0.1 or 4.0.3, but not necessarily with 4.1.0.
We do strive to maintain backwards compatibility for SPI contracts across minor versions, it is just not guaranteed.
Incubating
Code annotated with @Incubating
is not covered by this compatibility policy at all.
Incubating code can change at any time, even in a bugfix (micro) release. It may or may not become fully part of an API or SPI in a future release, potentially under a different form. It may be removed without replacement and without prior notice, including in a bugfix (micro) release.
Compatibility between Hibernate projects
Hibernate projects with the same version number are not automatically compatible.
There is no "release train" in Hibernate projects. Each Hibernate project releases new versions independently and picks the version of its dependencies according to its needs and compatibility requirements.
For example, Hibernate Search 5.11.5.Final depends on Hibernate ORM 5.4.12.Final. Hibernate ORM 5.11.5.Final does not even exist!
Compatibility with third-party software
This section discusses the expectations users should have regarding compatibility between Hibernate projects and third-party software.
Hibernate ORM and relational databases
RDBMS version
Each release of Hibernate ORM supports multiple versions of multiple Relational DataBase Management Systems (RDBMS, the piece of software giving access to one or more databases).
Supported versions of each RDBMS are stable across all releases within a minor version of Hibernate ORM.
For example, upgrading from Hibernate ORM 6.0.0.Final to 6.0.1.Final should not require upgrading to a newer version of your RDBMS, but upgrading from 6.0.1.Final to 6.1.0.Final may require upgrading to a newer version of your RDBMS.
Hibernate Search and Lucene
Hibernate Search provides ways to index entities directly in a local Lucene index. The following sections detail aspects of compatibility that are specific to Lucene.
Lucene version
Each release of Hibernate Search ties itself to one (and only one) specific version of Lucene.
Upgrading Hibernate Search, even in a bugfix (micro) update, may require upgrading Lucene.
For example, upgrading from Hibernate Search 6.0.0.Final to 6.0.1.Final may require an upgrade of Lucene.
Lucene index data
Lucene indexes are stored on disk (or otherwise) with a given format, which may change in incompatible ways when upgrading Hibernate Search or Lucene. In such an event, old indexes would be unusable in an upgraded application, which would require dropping indexes and reindexing all data.
Index format is stable across all releases within a minor version.
For example, upgrading from Hibernate Search 5.10.0.Final to 5.10.1.Final may require an upgrade of Lucene, but this Lucene upgrade should not require dropping indexes and reindexing. Upgrading from Hibernate Search 5.10.0.Final to 5.11.0.Final may require dropping indexes and reindexing.
Lucene API
- Hibernate Search 5 or earlier
-
Lucene APIs are largely leaking through Hibernate Search APIs.
Therefore, we try to provide the same level of backward compatibility for Lucene APIs as we do for our own APIs.
For example, upgrading from Hibernate Search 5.10.0.Final to 5.11.0.Final may require an upgrade of Lucene, but this Lucene upgrade should not introduce any breaking change in Lucene APIs. Upgrading from Hibernate Search 5.11.0.Final to 6.0.0.Final may introduce breaking changes in Lucene APIs.
- Hibernate Search 6 or later
-
Abstraction layers hide Lucene APIs, meaning applications generally do not need to rely on Lucene APIs at all. The only way to rely on Lucene APIs directly from user code is through extensions, for example to pass a Lucene Query directly to the Search DSL.
These extensions are not covered by the compatibility policy.
For example, upgrading from Hibernate Search 6.0.0.Final to 6.0.1.Final may require an upgrade of Lucene, and this Lucene upgrade may introduce breaking change in Lucene APIs.
Hibernate Search and Elasticsearch/OpenSearch
Hibernate Search provides ways to index entities in a remote Elasticsearch/OpenSearch cluster. The following sections detail aspects of compatibility that are specific to Elasticsearch/OpenSearch.
Elasticsearch/OpenSearch version
Each release of Hibernate Search supports multiple versions of Elasticsearch/OpenSearch.
Supported versions are stable across all releases within a minor version of Hibernate Search.
For example, upgrading from Hibernate Search 6.0.0.Final to 6.0.1.Final should not require upgrading to a newer version of Elasticsearch/OpenSearch, but upgrading from 6.0.1.Final to 6.1.0.Final may require upgrading to a newer version of Elasticsearch/OpenSearch.
Remote mapping and data
Elasticsearch/OpenSearch indexes are stored with a specific format, generally driven by the "mapping" assigned to the index, either of which may change in incompatible ways when upgrading Hibernate Search or Elasticsearch/OpenSearch. In such an event, old indexes would be unusable in an upgraded application, which would require dropping indexes and reindexing all data.
- Hibernate Search upgrades
-
The Elasticsearch/OpenSearch mapping generated by Hibernate Search for a given version of Elasticsearch/OpenSearch is stable across all releases within a minor version of Hibernate Search.
For example, upgrading from Hibernate Search 6.0.0.Final to 6.0.1.Final while staying on Elasticsearch 7.10.0 should not require dropping indexes or reindexing, but upgrading from 6.0.1.Final to 6.1.0.Final may require dropping indexes and reindexing.
The internal format of Elasticsearch/OpenSearch indexes is not affected by Hibernate Search upgrades.
- Elasticsearch/OpenSearch upgrades
-
Upgrading from one version of Elasticsearch/OpenSearch to the next, or from Elasticsearch to OpenSearch, may require dropping indexes and reindexing. This is true even when staying on the same version of Hibernate Search. It mainly depends on whether the Elasticsearch mapping API or internal index format changed in incompatible ways, which is out of the control of the Hibernate Search project.
User-provided JSON
Abstraction layers hide Elasticsearch/OpenSearch APIs, meaning users generally do not need to provide JSON directly: Hibernate Search will generate it automatically. The only way to rely on these APIs directly from user code is through extensions, for example when passing JSON to embed in a search request.
These extensions are not covered by the compatibility policy.
For example, upgrading from Elasticsearch 7.10.0 to 7.10.1 may require updating JSON hard-coded in application code, and Hibernate Search cannot do anything about it.