Hibernate.orgCommunity Documentation

第 2 章 体系结构(Architecture)

2.1. 概况(Overview)
2.2. 实例状态
2.3. JMX 整合
2.4. 对 JCA 的支持
2.5. 上下文相关的会话(Contextual Session)

下面的图表提供了 Hibernate 体系结构的高层视图:

提供 Hibernate 所有运行时体系结构的更多细节不是本文档的范畴。由于 Hibernate 非常灵活,且支持多种应用方案, 所以我们这只描述一下两种极端的情况:“最小”和“全面解决”的体系结构方案。

下图演示了 Hibernate 如何使用数据库和配置信息来为应用程序提供持久化服务(以及持久的对象)。

“最小”的体系结构方案,要求应用程序提供自己的 JDBC 连接并管理自己的事务。这种方案使用了Hibernate API 的最小子集:

“全面解决”的体系结构方案,将应用层从底层的 JDBC/JTA API 中抽象出来,而让 Hibernate 来处理这些细节。

图中各个对象的定义如下:

SessionFactory (org.hibernate.SessionFactory)

针对单个数据库映射关系经过编译后的内存镜像,是线程安全的(不可变)。 作为 Session 的工厂和 ConnectionProvider 的客户。SessionFactory 可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。

Session (org.hibernate.Session)

表示应用程序与持久储存层之间交互操作的一个单线程对象,此对象生存期很短。其隐藏了 JDBC 连接,也是 Transaction 的工厂。它会持有一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象时会用到。

持久的对象及其集合

带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的JavaBeans/POJO,唯一特殊的是他们正与(仅仅一个)Session 相关联。一旦这个 Session 被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用(例如,用作跟表示层打交道的数据传输对象)。

瞬态(transient)和脱管(detached)的对象及其集合

那些目前没有与 Session关联的持久化类实例。他们可能是在被应用程序实例化后,尚未进行持久化的对象。也可能是因为实例化他们的 Session 已经被关闭而脱离持久化的对象。

事务 Transaction (org.hibernate.Transaction)

(可选的)应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。它通过抽象将应用从底层具体的 JDBC、JTA 以及 CORBA 事务隔离开。某些情况下,一个 Session 之内可能包含多个 Transaction 对象。尽管是否使用该对象是可选的,但无论是使用底层的 API 还是使用 Transaction 对象,事务边界的开启与关闭是必需的。

ConnectionProvider (org.hibernate.connection.ConnectionProvider)

(可选的)生成 JDBC 连接的工厂(同时也起到连接池的作用)。它通过抽象将应用从底层的 DatasourceDriverManager 隔离开。仅供开发者扩展/实现用,并不开放给应用程序使用。

TransactionFactory (org.hibernate.TransactionFactory)

(可选的)生成 Transaction 对象实例的工厂。仅供开发者扩展/实现用,并不开发能够给应用程序使用。

Extension Interfaces

Hibernate 提供了很多可选的扩展接口,你可以通过实现它们来定制你的持久层的行为。具体请参考 API 文档。

在特定“最小”的体系结构中,应用程序可能绕过 Transaction/TransactionFactory 以及 ConnectionProvider 等 API 直接跟 JTA 或 JDBC 打交道。

一个持久化类的实例可能处于三种不同状态中的某一种。这三种状态的定义则与所谓的持久化上下文(persistence context)有关。Hibernate 的 Session 对象就是这个所谓的持久化上下文。这三种不同的状态如下:

JMX 是管理 Java 组件的 J2EE 标准。Hibernate 可以通过一个 JMX 标准服务来管理。在这个发行版本中,我们提供了一个 MBean 接口的实现,即 org.hibernate.jmx.HibernateService

想要看如何在 JBoss 应用服务器上将 Hibernate 部署为一个 JMX 服务的例子,您可以参考《JBoss 用户指南》。如果你使用 JMX 来部署 Hibernate,JBoss AS 也提供如下好处:

这些选项更多的描述,请参考 JBoss 应用程序用户指南。

Another feature available as a JMX service is runtime Hibernate statistics. See 第 3.4.6 节 “Hibernate 的统计(statistics)机制” for more information.

Hibernate 也可以被配置为一个 JCA 连接器(JCA connector)。更多信息请参看网站。请注意,Hibernate 对 JCA 的支持,仍处于实验性阶段。

使用 Hibernate 的大多数应用程序需要某种形式的“上下文相关的”会话,特定的会话在整个特定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这种“上下文”下一个定义通常是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在 3.0 版本之前,使用 Hibernate 的程序要么采用自行编写的基于 ThreadLocal 的上下文会话,要么采用 HibernateUtil 这样的辅助类,要么采用第三方框架(比如 Spring 或 Pico),它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关的会话。

从 3.0.1 版本开始,Hibernate 增加了 SessionFactory.getCurrentSession() 方法。一开始,它假定了采用 JTA 事务,JTA 事务定义了当前 session 的范围和上下文(scope 和 context)。因为有好几个独立的 JTA TransactionManager 实现稳定可用,不论是否被部署到一个 J2EE 容器中,大多数(假若不是所有的)应用程序都应该采用 JTA 事务管理。基于这一点,采用 JTA 的上下文相关的会话可以满足你一切需要。

更好的是,从 3.1 开始,SessionFactory.getCurrentSession() 的后台实现是可拔插的。因此,我们引入了新的扩展接口(org.hibernate.context.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class),以便对什么是当前会话的范围(scope)和上下文(context)的定义进行拔插。

请参阅 org.hibernate.context.CurrentSessionContext 接口的 Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,currentSession(),特定的实现用它来负责跟踪当前的上下文相关的会话。Hibernate 内置了此接口的三种实现:

The first two implementations provide a "one session - one database transaction" programming model. This is also known and used as session-per-request. The beginning and end of a Hibernate session is defined by the duration of a database transaction. If you use programmatic transaction demarcation in plain JSE without JTA, you are advised to use the Hibernate Transaction API to hide the underlying transaction system from your code. If you use JTA, you can utilize the JTA interfaces to demarcate transactions. If you execute in an EJB container that supports CMT, transaction boundaries are defined declaratively and you do not need any transaction or session demarcation operations in your code. Refer to 第 12 章 事务和并发 for more information and code examples.

hibernate.current_session_context_class 配置参数定义了应该采用哪个 org.hibernate.context.CurrentSessionContext 实现。注意,为了向下兼容,如果未配置此参数,但是存在 org.hibernate.transaction.TransactionManagerLookup 的配置,Hibernate 会采用org.hibernate.context.JTASessionContext。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即 "jta"、"thread" 和 "managed"。