您的应用程序与 Hibernate 库交互,而 Hibernate 库又与第三方软件交互:JDBC 驱动程序、其他库,甚至 REST API (Elasticsearch/OpenSearch)。当这些组件中的任何一个更改其 API 时,就会存在出现不兼容的风险。此页面说明了 Hibernate 项目如何尝试限制不兼容更改。

Hibernate 项目在最大努力的基础上遵守此兼容性策略。

对于有合同约束的保修,请考虑付费支持

概念

代码分类 (API/SPI/内部…​)

从概念上讲,我们将代码库中的类划分为 3 个大类

  • 应用程序编程接口 (API) 是提供给应用程序的一组合约。例如,Session#save。它是您的应用程序与 Hibernate 库交互的接口。这是我们完全期望编译器将您的应用程序字节码直接链接到您的应用程序字节码的代码。

  • 服务提供者接口 (SPI) 是与 Hibernate 库的“集成点”,以及执行这些集成的所需合约。它是框架或第三方库(缓存实现等)与 Hibernate 库集成的接口。

  • 内部是仅供 Hibernate 库内部使用的类和代码。

在大多数情况下,我们尝试通过将类放到包中来表示这些区别

  • 名为 internalimpl 的包中的类是内部的。

  • 名为 spi 的包中的类是 SPI。

  • 既没有 internalimpl 也没有 spi 的包中的类是 API。

对于 Hibernate ORM,以这种方式将代码分组到包中是一个持续的过程,并且尚未完成。我们无法批量执行的原因是,奇怪的是,向后兼容性。

此外,一些类、方法或字段可能会被注释以引入异常。

  • 使用@Internal注释的代码是内部代码。此注释用于由于技术限制或历史原因而通过 API 或 SPI 泄漏的代码。

  • 使用@Incubating注释的代码尚未成为 API 或 SPI 的一部分,但将来可能会成为。此注释用于仍在开发中且可能仍会发生不兼容变化的代码。

版本控制方案

Hibernate 项目根据以下方案进行版本控制

major.minor.micro.qualifier

其中

  • majorminormicro 是递增的整数。

  • qualifierAlpha1Alpha2 等,Beta1Beta2 等,用于开发版本,CR1CR2 等,用于候选版本,或Final,用于稳定版本。

例如:4.0.0.Final5.2.0.Beta25.4.0.CR1

在大多数情况下,我们遵循JBoss 项目版本控制指南中定义的指南,因此这是一个很好的背景资料。

但是,Hibernate 应用了一些额外的语义。粗略地说

  • 主要更新意味着对现有 API 的潜在不兼容更改。这可能包括删除一些 API。

  • 次要更新只是对现有 API 的添加。

  • 微更新仅用于修复错误。

  • Alpha/Beta 更新用于进行中的工作,可能会更改新引入的 API。

详细信息可以在后面的应用程序和 Hibernate 项目之间的兼容性中找到。

应用程序和 Hibernate 项目之间的兼容性

本节讨论用户对应用程序和 Hibernate 项目之间兼容性的期望。

以下原则只是指南。虽然我们尽力尽可能地遵循它们,但有时需要做出例外。

例如,如果 API 的一小部分的设计使其变得无用或会导致严重错误,我们可能会决定在错误修复(微)版本中以不兼容的方式更改它。

另一个例外是当向后移植对标准的支持时。我们可能会决定引入“过渡”次要版本,这些版本升级到标准的较新版本,同时保留其他所有地方的向后兼容性,以方便迁移到下一个主要版本。例如,Hibernate ORM 5.5 可能会升级到 Jakarta 9 的持久性 API(并且不更改其他任何内容),以方便迁移到 Hibernate ORM 6.0。

API

API 合约在**主要**版本中的所有版本中都保持稳定。

例如,如果您最初使用 Hibernate ORM 版本 4.0.0 开发了一个应用程序,并且该应用程序仅依赖于定义的 API,则期望您可以在其中放入任何更新的 Hibernate 4.x 版本,它将按预期工作。

这就是所谓的向后兼容性:在 4.3(例如)中所做的任何更改都是以保持与旧(向后)版本(一直追溯到 4.0)的兼容性进行的。

对于 API,我们实际上并不保证在回归到旧版本(恢复)方面的逆向操作。这里的例子是使用 4.2 中开发的 natural-id API 开发一个应用程序,然后尝试将 Hibernate ORM 4.1 或 4.0 放入该应用程序中。那样行不通。

因此,在主要版本中,我们保证 API 向后兼容,但不保证向前兼容。较新的版本可能会**添加到** API 中,但它们不应修改或删除。

SPI

SPI 合约在**次要**版本中的所有版本中都保持稳定,但在同一主要版本的不同次要版本中不一定保持稳定。

例如,针对 Hibernate ORM 4.0.0 开发的集成将适用于 4.0.1 或 4.0.3,但不一定适用于 4.1.0。

我们确实努力在次要版本之间保持 SPI 合约的向后兼容性,只是没有保证。

孵化阶段

使用@Incubating注释的代码**根本不**受此兼容性策略的约束。

孵化阶段代码随时可能发生变化,即使是在错误修复(微)版本中也是如此。它可能在将来某个版本中成为 API 或 SPI 的一部分,也可能不成为,并且可能以不同的形式出现。它可能会被删除而没有替换,并且没有任何事先通知,包括在错误修复(微)版本中。

内部代码

用户不应该对“内部”代码的兼容性抱有任何期望。内部类可能会随时更改甚至被删除,包括在微更新中。

Hibernate 项目之间的兼容性

具有相同版本号的 Hibernate 项目并不自动兼容.

Hibernate 项目中没有“发布列车”。每个 Hibernate 项目都独立发布新版本,并根据其需求和兼容性要求选择其依赖项的版本。

例如,Hibernate Search 5.11.5.Final 依赖于 Hibernate ORM 5.4.12.Final。Hibernate ORM 5.11.5.Final 甚至不存在!

为了帮助您选择兼容的版本,我们为每个项目提供了一个兼容性矩阵

与第三方软件的兼容性

本节讨论用户对 Hibernate 项目和第三方软件之间兼容性的期望。

在许多情况下,您可以使用相关项目的兼容性矩阵找到第三方依赖项的适当版本

Hibernate ORM 和关系数据库

RDBMS 版本

每个 Hibernate ORM 版本都支持多个关系数据库管理系统 (RDBMS,提供对一个或多个数据库访问的软件) 的多个版本。

每个 RDBMS 的支持版本在 Hibernate ORM 的**次要**版本中的所有版本中都保持稳定。

例如,从 Hibernate ORM 6.0.0.Final 升级到 6.0.1.Final 不需要升级到较新版本的 RDBMS,但从 6.0.1.Final 升级到 6.1.0.Final 可能需要升级到较新版本的 RDBMS。

Hibernate Search 和 Lucene

Hibernate Search 提供了将实体直接索引到本地 Lucene 索引中的方法。以下部分详细说明了特定于 Lucene 的兼容性方面。

Lucene 版本

每个 Hibernate Search 版本都绑定到一个(且仅一个)特定版本的 Lucene。

升级 Hibernate Search,即使是在错误修复(微)更新中,也**可能**需要升级 Lucene。

例如,从 Hibernate Search 6.0.0.Final 升级到 6.0.1.Final 可能需要升级 Lucene。

Lucene 索引数据

Lucene 索引以给定格式存储在磁盘(或其他位置)上,在升级 Hibernate Search 或 Lucene 时,该格式可能会以不兼容的方式更改。在这种情况下,旧索引在升级后的应用程序中将不可用,这将需要删除索引并重新索引所有数据。

索引格式在**次要**版本中的所有版本中都保持稳定。

例如,从 Hibernate Search 5.10.0.Final 升级到 5.10.1.Final 可能需要升级 Lucene,但此 Lucene 升级**不应**需要删除索引并重新索引。从 Hibernate Search 5.10.0.Final 升级到 5.11.0.Final**可能**需要删除索引并重新索引。

Lucene API

Hibernate Search 5 或更早版本

Lucene API 在很大程度上通过 Hibernate Search API 泄漏。

因此,我们尝试为 Lucene API 提供与我们对自身 API 所做的一样的向后兼容性级别。

例如,从 Hibernate Search 5.10.0.Final 升级到 5.11.0.Final 可能需要升级 Lucene,但此 Lucene 升级**不应**在 Lucene API 中引入任何重大更改。从 Hibernate Search 5.11.0.Final 升级到 6.0.0.Final**可能**在 Lucene API 中引入重大更改。

Hibernate Search 6 或更高版本

抽象层隐藏了 Lucene API,这意味着应用程序通常根本不需要依赖 Lucene API。从用户代码直接依赖 Lucene API 的唯一方法是通过扩展,例如将 Lucene 查询直接传递到 Search DSL

这些扩展不属于兼容性策略的约束范围。

例如,从 Hibernate Search 6.0.0.Final 升级到 6.0.1.Final 可能需要升级 Lucene,并且此 Lucene 升级**可能**在 Lucene API 中引入重大更改。

Hibernate Search 和 Elasticsearch/OpenSearch

Hibernate Search 提供了将实体索引到远程 Elasticsearch/OpenSearch 集群中的方法。以下部分详细说明了特定于 Elasticsearch/OpenSearch 的兼容性方面。

Elasticsearch/OpenSearch 版本

每个 Hibernate Search 版本都支持多个版本的 Elasticsearch/OpenSearch。

支持的版本在 Hibernate Search 的**次要**版本中的所有版本中都保持稳定。

例如,从 Hibernate Search 6.0.0.Final 升级到 6.0.1.Final**不应**需要升级到较新版本的 Elasticsearch/OpenSearch,但从 6.0.1.Final 升级到 6.1.0.Final**可能**需要升级到较新版本的 Elasticsearch/OpenSearch。

远程映射和数据

Elasticsearch/OpenSearch 索引以特定格式存储,通常由分配给索引的“映射”驱动,其中任何一个都可能在升级 Hibernate Search 或 Elasticsearch/OpenSearch 时以不兼容的方式更改。在这种情况下,旧索引在升级后的应用程序中将不可用,这将需要删除索引并重新索引所有数据。

Hibernate Search 升级

Hibernate Search 为特定版本的 Elasticsearch/OpenSearch 生成的 Elasticsearch/OpenSearch 映射在 Hibernate Search 的**次要**版本中的所有版本中都保持稳定。

例如,从 Hibernate Search 6.0.0.Final 升级到 6.0.1.Final,同时保持在 Elasticsearch 7.10.0 上**不应**需要删除索引或重新索引,但从 6.0.1.Final 升级到 6.1.0.Final**可能**需要删除索引并重新索引。

Elasticsearch/OpenSearch 索引的内部格式不受 Hibernate Search 升级的影响。

Elasticsearch/OpenSearch 升级

从一个版本的 Elasticsearch/OpenSearch 升级到下一个版本,或者从 Elasticsearch 升级到 OpenSearch,**可能**需要删除索引并重新索引。即使是在使用相同版本的 Hibernate Search 的情况下也是如此。这主要取决于 Elasticsearch 映射 API 或内部索引格式是否以不兼容的方式发生更改,而这不受 Hibernate Search 项目的控制。

用户提供的 JSON

抽象层隐藏了 Elasticsearch/OpenSearch API,这意味着用户通常不需要直接提供 JSON:Hibernate Search 将自动生成 JSON。从用户代码直接依赖这些 API 的唯一方法是通过扩展,例如当传递 JSON 以嵌入到搜索请求中时

这些扩展不属于兼容性策略的约束范围。

例如,从 Elasticsearch 7.10.0 升级到 7.10.1 可能需要更新在应用程序代码中硬编码的 JSON,而 Hibernate Search 对此无能为力。

返回顶部