Hibernate 5 Bootstrapping API – Hibernate 5 Bootstrapping API

最后修改: 2018年 12月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll explore the new mechanism by which we can initialize and start a Hibernate SessionFactory. We’ll especially focus on the new native bootstrapping process as it was redesigned in version 5.0.

在本教程中,我们将探索新的机制,通过该机制我们可以初始化和启动Hibernate SessionFactory。我们将特别关注新的本地引导过程,因为它在5.0版本中被重新设计。

Prior to version 5.0, applications had to use the Configuration class to bootstrap the SessionFactory. This approach is now deprecated, as the Hibernate documentation recommends using the new API based on the ServiceRegistry.

在5.0版本之前,应用程序必须使用Configuration类来引导SessionFactory。这种方法现在已被废弃,因为Hibernate文档建议使用基于ServiceRegistry的新API。

Simply put, building a SessionFactory is all about having a ServiceRegistry implementation that holds the Services needed by Hibernate during both startup and runtime.

简单地说,构建一个SessionFactory就是要有一个ServiceRegistry实现,在启动和运行时都持有Hibernate需要的Services

2. Maven Dependencies

2.Maven的依赖性

Before we start exploring the new bootstrapping process, we need to add the hibernate-core jar file to the project classpath. In a Maven based project, we just need to declare this dependency in the pom.xml file:

在我们开始探索新的引导过程之前,我们需要将hibernate-core jar文件添加到项目classpath中。在基于Maven的项目中,我们只需要在pom.xml文件中声明这一依赖关系。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.0.Final</version>
</dependency>

As Hibernate is a JPA provider, this will also include the JPA API dependency transitively.

由于Hibernate是一个JPA提供者,这也将包括JPA API的依赖性。

We also need the JDBC driver of the database that we’re working with. In this example, we’ll use an embedded H2 database:

我们还需要我们所使用的数据库的JDBC驱动程序。在这个例子中,我们将使用一个嵌入式H2数据库。

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.197</version>
</dependency>

Feel free to check the latest versions of hibernate-core and H2 driver on Maven Central.

请随时在Maven中心查看hibernate-coreH2驱动的最新版本。

3. Bootstrapping API

3.Bootstrapping API

Bootstrapping refers to the process of building and initializing a SessionFactory.

引导是指建立和初始化一个SessionFactory的过程。

To achieve this purpose, we need to have a ServiceRegistry that holds the Services needed by Hibernate. From this registry, we can build a Metadata object that represents the application’s domain model and its mapping to the database.

为了实现这一目的,我们需要有一个ServiceRegistry,它持有Hibernate需要的Services。从这个注册表中,我们可以建立一个Metadata对象,代表应用程序的领域模型及其与数据库的映射

Let’s explore these major objects in greater detail.

让我们更详细地探讨这些主要对象。

3.1. Service

3.1.服务

Before we dig into the ServiceRegistry concept, we first need to understand what a Service is. In Hibernate 5.0, a Service is a type of functionality represented by the interface with the same name:

在我们深入探讨ServiceRegistry概念之前,我们首先需要了解什么是Service在Hibernate 5.0中,Service是一种由同名接口代表的功能类型。

org.hibernate.service.Service

By default, Hibernate provides implementations for the most common Services, and they are sufficient in most cases. Otherwise, we can build our own Services to either modify original Hibernate functionalities or add new ones.

默认情况下,Hibernate为最常见的Services提供了实现,它们在大多数情况下是足够的。否则,我们可以构建自己的Services,以修改原有的Hibernate功能或添加新的功能。

In the next subsection, we’ll show how Hibernate makes these Services available through a lightweight container called ServiceRegistry.

在下一小节中,我们将展示Hibernate如何通过一个名为ServiceRegistry的轻量级容器使这些Services可用。

3.2. ServiceRegistry

3.2.服务注册表

The first step in building a SessionFactory is to create a ServiceRegistry. This allows holding various Services that provide functionalities needed by Hibernate and is based on the Java SPI functionality.

构建SessionFactory的第一步是创建ServiceRegistry。这允许持有各种Services,它们提供Hibernate所需的功能,并且基于Java SPI功能。

Technically speaking, we can see the ServiceRegistry as a lightweight Dependency Injection tool where beans are only of type Service.

从技术上讲,我们可以将ServiceRegistry看作是一个轻量级的依赖注入工具,其中的Bean只有Service.类型。

There are two types of ServiceRegistry and they are hierarchical. The first is the BootstrapServiceRegistry, which has no parent and holds these three required services:

有两种类型的ServiceRegistry,它们是分层的 第一种是BootstrapServiceRegistry,它没有父级,持有这三种必要的服务

  • ClassLoaderService: allows Hibernate to interact with the ClassLoader of the various runtime environments
  • IntegratorService: controls the discovery and management of the Integrator service allowing third-party applications to integrate with Hibernate
  • StrategySelector: resolves implementations of various strategy contracts

To build a BootstrapServiceRegistry implementation, we use the BootstrapServiceRegistryBuilder factory class, which allows customizing these three services in a type-safe manner:

为了构建一个BootstrapServiceRegistry实现,我们使用BootstrapServiceRegistryBuilder工厂类,它允许以一种类型安全的方式定制这三种服务。

BootstrapServiceRegistry bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder()
  .applyClassLoader()
  .applyIntegrator()
  .applyStrategySelector()
  .build();

The second ServiceRegistry is the StandardServiceRegistry, which builds on the previous BootstrapServiceRegistry and holds the three Services mentioned above. Additionally, it contains various other Services needed by Hibernate, listed in the StandardServiceInitiators class.

第二个ServiceRegistryStandardServiceRegistry,它建立在之前的BootstrapServiceRegistry之上,并持有上面提到的三个Services。此外,它还包含 Hibernate 所需的其他各种服务,这些服务在 StandardServiceInitiators 类中列出。

Like the previous registry, we use the StandardServiceRegistryBuilder to create an instance of the StandardServiceRegistry:

与之前的注册表一样,我们使用StandardServiceRegistryBuilder来创建StandardServiceRegistry>的实例:

StandardServiceRegistryBuilder standardServiceRegistry =
  new StandardServiceRegistryBuilder();

Under the hood, the StandardServiceRegistryBuilder creates and uses an instance of BootstrapServiceRegistry. We can also use an overloaded constructor to pass an already created instance:

在引擎盖下,StandardServiceRegistryBuilder创建并使用BootstrapServiceRegistry.的一个实例,我们也可以使用重载构造函数来传递一个已经创建的实例。

BootstrapServiceRegistry bootstrapServiceRegistry = 
  new BootstrapServiceRegistryBuilder().build();
StandardServiceRegistryBuilder standardServiceRegistryBuilder = 
  new StandardServiceRegistryBuilder(bootstrapServiceRegistry);

We use this builder to load a configuration from a resource file, such as the default hibernate.cfg.xml, and finally, we invoke the build() method to get an instance of the StandardServiceRegistry.

我们使用这个构建器从资源文件中加载配置,例如默认的hibernate.cfg.xml,最后,我们调用build()方法来获取StandardServiceRegistry.的一个实例。

StandardServiceRegistry standardServiceRegistry = standardServiceRegistryBuilder
  .configure()
  .build();

3.3. Metadata

3.3.元数据

Having configured all the Services needed by instantiating a ServiceRegistry either of type BootstrapServiceRegistry or StandardServiceRegistry, we now need to provide the representation of the application’s domain model and its database mapping.

在通过实例化ServiceRegistry(类型为BootstrapServiceRegistry或StandardServiceRegistry)配置了所有需要的Services后,我们现在需要提供应用程序的领域模型及其数据库映射的表示。

The MetadataSources class is responsible for this:

MetadataSources类负责这项工作。

MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
metadataSources.addAnnotatedClass();
metadataSources.addResource()

Next, we get an instance of Metadata, which we’ll use in the last step:

接下来,我们得到一个Metadata的实例,我们将在最后一步使用它。

Metadata metadata = metadataSources.buildMetadata();

3.4. SessionFactory

3.4.SessionFactory

The last step is to create the SessionFactory from the previously created Metadata:

最后一步是根据先前创建的Metadata:创建SessionFactory

SessionFactory sessionFactory = metadata.buildSessionFactory();

We can now open a Session and start persisting and reading entities:

我们现在可以打开一个Session并开始持久化和读取实体。

Session session = sessionFactory.openSession();
Movie movie = new Movie(100L);
session.persist(movie);
session.createQuery("FROM Movie").list();

4. Conclusion

4.结论

In this article, we explored the steps needed to build a SessionFactory. Although the process seems complex, we can summarize it in three major steps: we first created an instance of StandardServiceRegistry, then we built a Metadata object, and finally, we built the SessionFactory.

在本文中,我们探讨了构建SessionFactory所需的步骤。虽然这个过程看起来很复杂,但我们可以将其总结为三个主要步骤:我们首先创建了StandardServiceRegistry的实例,然后我们构建了Metadata对象,最后,我们构建了SessionFactory。

The full code for these examples can be found over on Github.

这些例子的完整代码可以在Github上找到over