Hibernate.org Community Documentation
由于 Hibernate 是为了能在各种不同环境下工作而设计的,因此存在着大量的配置参数。幸运的是多数配置参数都有比较直观的默认值,并有随 Hibernate 一同分发的配置样例 hibernate.properties
(位于 etc/
)来展示各种配置选项。所需做的仅仅是将这个样例文件复制到类路径(classpath)下并进行定制。
org.hibernate.cfg.Configuration
实例代表了一个应用程序中 Java 类型到SQL数据库映射的完整集合。org.hibernate.cfg.Configuration
被用来构建一个(不可变的(immutable))org.hibernate.SessionFactory
。映射定义则由不同的 XML 映射定义文件编译而来。
你可以直接实例化 org.hibernate.cfg.Configuration
来获取一个实例,并为它指定 XML 映射定义文件。如果映射定义文件在类路径(classpath)中,请使用 addResource()
。例如:
Configuration cfg = new Configuration() .addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");
一个替代方法(有时是更好的选择)是,指定被映射的类,让 Hibernate 帮你寻找映射定义文件:
Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class);
Hibernate 将会在类路径(classpath)中寻找名字为 /org/hibernate/auction/Item.hbm.xml
和 /org/hibernate/auction/Bid.hbm.xml
映射定义文件。这种方式消除了任何对文件名的硬编码(hardcoded)。
org.hibernate.cfg.Configuration
> 也允许你指定配置属性。例如:
Configuration cfg = new Configuration()
.addClass(org.hibernate.auction.Item.class)
.addClass(org.hibernate.auction.Bid.class)
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
.setProperty("hibernate.order_updates", "true");
当然这不是唯一的传递 Hibernate 配置属性的方式,其他可选方式还包括:
-
传一个
java.util.Properties
实例给Configuration.setProperties()
。 -
将
hibernate.properties
放置在类路径(classpath)的根目录下(root directory)。 -
通过
java -Dproperty=value
来设置系统(System
)属性。 -
在
hibernate.cfg.xml
中加入元素<property>
(稍后讨论)。
如果你想快速上路,hibernate.properties
就是最容易的途径。
org.hibernate.cfg.Configuration
实例被设计成启动期间(startup-time)对象,一旦 SessionFactory
创建完成它就被丢弃了。
当所有映射定义被 org.hibernate.cfg.Configuration
解析后,应用程序必须获得一个用于构造 org.hibernate.Session
实例的工厂。这个工厂将被应用程序的所有线程共享:
SessionFactory sessions = cfg . buildSessionFactory ();
Hibernate 允许你的应用程序创建多个 org.hibernate.SessionFactory
实例。这对 使用多个数据库的应用来说很有用。
通常你希望 org.hibernate.SessionFactory
来为你创建和缓存(pool)JDBC 连接。如果你采用这种方式,只需要如下例所示那样,打开一个 org.hibernate.Session
:
Session session = sessions . openSession (); // open a new Session
一旦你需要进行数据访问时,就会从连接池(connection pool)获得一个 JDBC 连接。
为了使这种方式工作起来,我们需要向 Hibernate 传递一些 JDBC 连接的属性。所有 Hibernate 属性的名字和语义都在 org.hibernate.cfg.Environment
中定义。我们现在将描述 JDBC 连接配置中最重要的设置。
如果你设置如下属性,Hibernate 将使用 java.sql.DriverManager
来获得(和缓存)JDBC 连接:
表 3.1. Hibernate JDBC 属性
属性名 | 用途 |
---|---|
hibernate.connection.driver_class | JDBC driver class |
hibernate.connection.url | JDBC URL |
hibernate.connection.username | database user |
hibernate.connection.password | 数据库用户密码 |
hibernate.connection.pool_size | maximum number of pooled connections |
但 Hibernate 自带的连接池算法相当不成熟。它只是为了让你快些上手,并不适合用于产品系统或性能测试中。 出于最佳性能和稳定性考虑你应该使用第三方的连接池。只需要用特定连接池的设置替换 hibernate.connection.pool_size
即可。这将关闭 Hibernate 自带的连接池。例如,你可能会想用 C3P0。
C3P0 是一个随 Hibernate 一同分发的开源的 JDBC 连接池,它位于 lib
目录下。 如果你设置了 hibernate.c3p0.*
相关的属性,Hibernate将使用 C3P0ConnectionProvider
来缓存 JDBC 连接。如果你更原意使用 Proxool,请参考发行包中的 hibernate.properties
并到 Hibernate 网站获取更多的信息。
这是一个使用 C3P0 的 hibernate.properties
样例文件:
hibernate.connection.driver_class = org.postgresql.Driver hibernate.connection.url = jdbc:postgresql://localhost/mydatabase hibernate.connection.username = myuser hibernate.connection.password = secret hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50 hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
为了能在应用程序服务器(application server)中使用 Hibernate,应当总是将 Hibernate 配置成从注册在 JNDI 中的 Datasource
处获得连接,你至少需要设置下列属性中的一个:
表 3.2. Hibernate 数据源属性
属性名 | 用途 |
---|---|
hibernate.connection.datasource | 数据源 JNDI 名字 |
hibernate.jndi.url | JNDI 提供者的 URL(可选) |
hibernate.jndi.class | JNDI InitialContextFactory 类(可选) |
hibernate.connection.username | 数据库用户(可选) |
hibernate.connection.password | 数据库密码(可选) |
这是一个使用应用程序服务器提供的 JNDI 数据源的 hibernate.properties
样例文件:
hibernate.connection.datasource = java:/comp/env/jdbc/test hibernate.transaction.factory_class = \ org.hibernate.transaction.JTATransactionFactory hibernate.transaction.manager_lookup_class = \ org.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
从 JNDI 数据源获得的 JDBC 连接将自动参与到应用程序服务器中容器管理的事务(container-managed transactions)中去。
任何连接(connection)属性的属性名都要以 "hibernate.connnection
" 开头。例如,你可能会使用 hibernate.connection.charSet
来指定 charSet 连接属性。
通过实现 org.hibernate.connection.ConnectionProvider
接口,你可以定义属于你自己的获得JDBC连接的插件策略。通过设置hibernate.connection.provider_class
,你可以选择一个自定义的实现。
有大量属性能用来控制 Hibernate 在运行期的行为。它们都是可选的,并拥有适当的默认值。
警告
其中一些属性是"系统级(system-level)的"。系统级属性只能通过java -Dproperty=value
或 hibernate.properties
来设置,而不能用上面描述的其他方法来设置。
表 3.3. Hibernate 配置属性
属性名 | 用途 |
---|---|
hibernate.dialect | 允许 Hibernate 针对特定的关系数据库生成优化的 SQL 的 org.hibernate.dialect.Dialect 的类名。 例如: 在大多数情况下,Hibernate 可以根据 JDBC 驱动返回的 |
hibernate.show_sql | 输出所有 SQL 语句到控制台。有一个另外的选择是把 org.hibernate.SQL 这个 log category设为 debug 。 例如: |
hibernate.format_sql | 在 log 和 console 中打印出更漂亮的 SQL。 例如: |
hibernate.default_schema | 在生成的 SQL 中,将给定的 schema/tablespace 附加于非全限定名的表名上。 例如: |
hibernate.default_catalog | 在生成的 SQL 中,将给定的 catalog 附加于非全限定名的表名上。 例如: |
hibernate.session_factory_name | org.hibernate.SessionFactory 创建后,将自动使用这个名字绑定到 JNDI 中。 例如: |
hibernate.max_fetch_depth | 为单向关联(一对一,多对一)的外连接抓取(outer join fetch)树设置最大深度。值为 0 意味着将关闭默认的外连接抓取。 例如: 建议在 |
hibernate.default_batch_fetch_size | 为 Hibernate 关联的批量抓取设置默认数量。 例如:建议的取值为 |
hibernate.default_entity_mode | 为由这个 SessionFactory 打开的所有 Session 指定默认的实体表现模式。 取值 |
hibernate.order_updates | 强制 Hibernate 按照被更新数据的主键,为 SQL 更新排序。这么做将减少在高并发系统中事务的死锁。 例如: |
hibernate.generate_statistics | 如果开启,Hibernate 将收集有助于性能调节的统计数据。 例如: |
hibernate.use_identifier_rollback | 如果开启,在对象被删除时生成的标识属性将被重设为默认值。 例如: |
hibernate.use_sql_comments | 如果开启,Hibernate 将在 SQL 中生成有助于调试的注释信息,默认值为 false 。 例如: |
hibernate.id.new_generator_mappings | Setting is relevant when using @GeneratedValue . It indicates whether or not the new IdentifierGenerator implementations are used for javax.persistence.GenerationType.AUTO , javax.persistence.GenerationType.TABLE and javax.persistence.GenerationType.SEQUENCE . Default to false to keep backward compatibility. 例如: |
注意
We recommend all new projects which make use of to use @GeneratedValue
to also set hibernate.id.new_generator_mappings=true
as the new generators are more efficient and closer to the JPA 2 specification semantic. However they are not backward compatible with existing databases (if a sequence or a table is used for id generation).
表 3.4. Hibernate JDBC 和连接(connection)属性
属性名 | 用途 |
---|---|
hibernate.jdbc.fetch_size | 非零值,指定 JDBC 抓取数量的大小(调用 Statement.setFetchSize() )。 |
hibernate.jdbc.batch_size | 非零值,允许 Hibernate 使用 JDBC2 的批量更新。 例如:建议取 |
hibernate.jdbc.batch_versioned_data | Set this property to true if your JDBC driver returns correct row counts from executeBatch() . It is usually safe to turn this option on. Hibernate will then use batched DML for automatically versioned data. Defaults to false . 例如: |
hibernate.jdbc.factory_class | 选择一个自定义的 Batcher 。多数应用程序不需要这个配置属性。 例如: |
hibernate.jdbc.use_scrollable_resultset | 允许 Hibernate 使用 JDBC2 的可滚动结果集。只有在使用用户提供的 JDBC 连接时,这个选项才是必要的,否则 Hibernate 会使用连接的元数据。 例如: |
hibernate.jdbc.use_streams_for_binary | 在 JDBC 读写 binary 或 serializable 的类型时使用流(stream)(系统级属性)。 例如: |
hibernate.jdbc.use_get_generated_keys | 在数据插入数据库之后,允许使用 JDBC3 PreparedStatement.getGeneratedKeys() 来获取数据库生成的 key(键)。需要 JDBC3+ 驱动和 JRE1.4+,如果你的数据库驱动在使用 Hibernate 的标识生成器时遇到问题,请将此值设为 false。默认情况下将使用连接的元数据来判定驱动的能力。 例如: |
hibernate.connection.provider_class | 自定义 ConnectionProvider 的类名,此类用来向 Hibernate 提供 JDBC 连接。 例如: |
hibernate.connection.isolation | 设置 JDBC 事务隔离级别。查看 java.sql.Connection 来了解各个值的具体意义,但请注意多数数据库都不支持所有的隔离级别。 例如: |
hibernate.connection.autocommit | 允许被缓存的 JDBC 连接开启自动提交(autocommit)(不推荐)。 例如: |
hibernate.connection.release_mode | 指定 Hibernate 在何时释放 JDBC 连接。默认情况下,直到 Session 被显式关闭或被断开连接时,才会释放 JDBC 连接。对于应用程序服务器的 JTA 数据源,你应当使用 after_statement ,这样在每次 JDBC 调用后,都会主动的释放连接。对于非 JTA 的连接,使用 after_transaction 在每个事务结束时释放连接是合理的。auto 将为 JTA 和 CMT 事务策略选择 after_statement ,为JDBC事务策略选择 after_transaction 。 例如: This setting only affects |
hibernate.connection. <propertyName> | 把 JDBC 属性 <propertyName> 传递给 DriverManager.getConnection() 。 |
hibernate.jndi. <propertyName> | 把 <propertyName> 属性传递给 JNDI InitialContextFactory 。 |
表 3.5. Hibernate 缓存属性
属性名 | 用途 |
---|---|
hibernate.cache.provider_class
|
自定义的 CacheProvider 的类名。 例如: |
hibernate.cache.use_minimal_puts
|
以频繁的读操作为代价,优化二级缓存来最小化写操作。在 Hibernate3 中,这个设置对的集群缓存非常有用,对集群缓存的实现而言,默认是开启的。 例如: |
hibernate.cache.use_query_cache
|
允许查询缓存,个别查询仍然需要被设置为可缓存的。 例如: |
hibernate.cache.use_second_level_cache
|
能用来完全禁止使用二级缓存。对那些在类的映射定义中指定 <cache> 的类,会默认开启二级缓存。 例如: |
hibernate.cache.query_cache_factory
|
自定义实现 QueryCache 接口的类名,默认为内建的 StandardQueryCache 。 例如: |
hibernate.cache.region_prefix
|
二级缓存区域名的前缀。 例如: |
hibernate.cache.use_structured_entries
|
强制 Hibernate 以更人性化的格式将数据存入二级缓存。 例如: |
hibernate.cache.default_cache_concurrency_strategy
|
Setting used to give the name of the default org.hibernate.annotations.CacheConcurrencyStrategy to use when either @Cacheable or @Cache is used. @Cache(strategy="..") is used to override this default. |
表 3.6. Hibernate 事务属性
属性名 | 用途 |
---|---|
hibernate.transaction.factory_class
|
一个 TransactionFactory 的类名,用于 Hibernate Transaction API(默认为 JDBCTransactionFactory )。 例如: |
jta.UserTransaction
|
一个 JNDI 名字,被 JTATransactionFactory 用来从应用服务器获取 JTA UserTransaction 。 例如: |
hibernate.transaction.manager_lookup_class
|
一个 TransactionManagerLookup 的类名 — 当使用 JVM 级缓存,或在 JTA 环境中使用 hilo 生成器的时候需要该类。 例如: |
hibernate.transaction.flush_before_completion
|
If enabled, the session will be automatically flushed during the before completion phase of the transaction. Built-in and automatic session context management is preferred, see 第 2.3 节 “上下文相关的会话(Contextual Session)”. 例如: |
hibernate.transaction.auto_close_session
|
If enabled, the session will be automatically closed during the after completion phase of the transaction. Built-in and automatic session context management is preferred, see 第 2.3 节 “上下文相关的会话(Contextual Session)”. 例如: |
表 3.7. 其他属性
属性名 | 用途 |
---|---|
hibernate.current_session_context_class
|
Supply a custom strategy for the scoping of the "current" Session . See 第 2.3 节 “上下文相关的会话(Contextual Session)” for more information about the built-in strategies. 例如: |
hibernate.query.factory_class
|
选择 HQL 解析器的实现。 例如: |
hibernate.query.substitutions
|
将 Hibernate 查询中的符号映射到 SQL 查询中的符号(符号可能是函数名或常量名字)。 例如: |
hibernate.hbm2ddl.auto
|
在 SessionFactory 创建时,自动检查数据库结构,或者将数据库 schema 的 DDL 导出到数据库。使用 create-drop 时,在显式关闭 SessionFactory 时,将删除掉数据库 schema。 例如: |
hibernate.hbm2ddl.import_files
|
Comma-separated names of the optional files containing SQL DML statements executed during the File order matters, the statements of a give file are executed before the statements of the following files. These statements are only executed if the schema is created ie if e.g. |
hibernate.bytecode.use_reflection_optimizer
|
Enables the use of bytecode manipulation instead of runtime reflection. This is a System-level property and cannot be set in 例如: |
hibernate.bytecode.provider
|
Both javassist or cglib can be used as byte manipulation engines; the default is e.g. |
你应当总是为你的数据库将 hibernate.dialect
属性设置成正确的 org.hibernate.dialect.Dialect
子类。如果你指定一种方言,Hibernate 将为上面列出的一些属性使用合理的默认值,这样你就不用手工指定它们。
表 3.8. Hibernate SQL 方言(hibernate.dialect
)
RDBMS | Dialect |
---|---|
DB2 |
org.hibernate.dialect.DB2Dialect
|
DB2 AS/400 |
org.hibernate.dialect.DB2400Dialect
|
DB2 OS390 |
org.hibernate.dialect.DB2390Dialect
|
PostgreSQL |
org.hibernate.dialect.PostgreSQLDialect
|
MySQL5 |
org.hibernate.dialect.MySQL5Dialect
|
MySQL5 with InnoDB |
org.hibernate.dialect.MySQL5InnoDBDialect
|
MySQL with MyISAM |
org.hibernate.dialect.MySQLMyISAMDialect
|
Oracle(any version) |
org.hibernate.dialect.OracleDialect
|
Oracle 9i |
org.hibernate.dialect.Oracle9iDialect
|
Oracle 10g |
org.hibernate.dialect.Oracle10gDialect
|
Oracle 11g |
org.hibernate.dialect.Oracle10gDialect
|
Sybase |
org.hibernate.dialect.SybaseASE15Dialect
|
Sybase Anywhere |
org.hibernate.dialect.SybaseAnywhereDialect
|
Microsoft SQL Server 2000 |
org.hibernate.dialect.SQLServerDialect
|
Microsoft SQL Server 2005 |
org.hibernate.dialect.SQLServer2005Dialect
|
Microsoft SQL Server 2008 |
org.hibernate.dialect.SQLServer2008Dialect
|
SAP DB |
org.hibernate.dialect.SAPDBDialect
|
Informix |
org.hibernate.dialect.InformixDialect
|
HypersonicSQL |
org.hibernate.dialect.HSQLDialect
|
H2 Database |
org.hibernate.dialect.H2Dialect
|
Ingres |
org.hibernate.dialect.IngresDialect
|
Progress |
org.hibernate.dialect.ProgressDialect
|
Mckoi SQL |
org.hibernate.dialect.MckoiDialect
|
Interbase |
org.hibernate.dialect.InterbaseDialect
|
Pointbase |
org.hibernate.dialect.PointbaseDialect
|
FrontBase |
org.hibernate.dialect.FrontbaseDialect
|
Firebird |
org.hibernate.dialect.FirebirdDialect
|
如果你的数据库支持 ANSI、Oracle 或 Sybase 风格的外连接,外连接抓取通常能通过限制往返数据库次数(更多的工作交由数据库自己来完成)来提高效率。外连接抓取允许在单个 SELECT
SQL 语句中, 通过 many-to-one、one-to-many、many-to-many 和 one-to-one 关联获取连接对象的整个对象图。
将 hibernate.max_fetch_depth
设为 0
能在全局 范围内禁止外连接抓取。设为 1
或更高值能启用 one-to-one 和 many-to-oneouter 关联的外连接抓取,它们通过 fetch="join"
来映射。
See 第 21.1 节 “抓取策略(Fetching strategies)” for more information.
Oracle 限制那些通过 JDBC 驱动传输的字节
数组的数目。如果你希望使用二进值(binary)
或 可序列化的(serializable)
类型的大对象,你应该开启 hibernate.jdbc.use_streams_for_binary
属性。这是系统级属性。
The properties prefixed by hibernate.cache
allow you to use a process or cluster scoped second-level cache system with Hibernate. See the 第 21.2 节 “二级缓存(The Second Level Cache)” for more information.
你可以使用 hibernate.query.substitutions
在 Hibernate 中定义新的查询符号。例如:
hibernate.query.substitutions true=1,false=0
将导致符号 true
和 false
在生成的 SQL 中被翻译成整数常量。
hibernate.query.substitutions toLowercase=LOWER
将允许你重命名 SQL 中的 LOWER
函数。
如果你开启 hibernate.generate_statistics
,那么当你通过 SessionFactory.getStatistics()
调整正在运行的系统时,Hibernate 将导出大量有用的数据。Hibernate 甚至能被配置成通过 JMX 导出这些统计信息。参考 org.hibernate.stats
中接口的 Javadoc,以获得更多信息。
Hibernate 利用 Simple Logging Facade for Java (SLF4J) 来记录不同系统事件的日志。SLF4J 可以根据你选择的绑定把日志输出到几个日志框架(NOP、Simple、log4j version 1.2、JDK 1.4 logging、JCL 或 logback)上。为了设置日志,你需要在 classpath 里加入 slf4j-api.jar
和你选择的绑定的 JAR 文件(使用 Log4J 时加入 slf4j-log4j12.jar
)。更多的细节请参考 SLF4J 文档。要使用 Log4j,你也需要在 classpath 里加入 log4j.properties
文件。Hibernate 里的 src/
目录里带有一个属性文件的例子。
我们强烈建议你熟悉一下 Hibernate 的日志消息。在不失可读性的前提下,我们做了很多工作,使 Hibernate 的日志可能地详细。这是必要的查错利器。最令人感兴趣的日志分类有如下这些:
表 3.9. Hibernate 日志类别
类别 | 功能 |
---|---|
org.hibernate.SQL
|
在所有 SQL DML 语句被执行时为它们记录日志 |
org.hibernate.type
|
为所有 JDBC 参数记录日志 |
org.hibernate.tool.hbm2ddl
|
在所有 SQL DDL 语句执行时为它们记录日志 |
org.hibernate.pretty
|
在 session 清洗(flush)时,为所有与其关联的实体(最多 20 个)的状态记录日志 |
org.hibernate.cache
|
为所有二级缓存的活动记录日志 |
org.hibernate.transaction
|
为事务相关的活动记录日志 |
org.hibernate.jdbc
|
为所有 JDBC 资源的获取记录日志 |
org.hibernate.hql.ast.AST
|
在解析查询的时候,记录 HQL 和 SQL 的 AST 分析日志 |
org.hibernate.secure
|
为 JAAS 认证请求做日志 |
org.hibernate
|
为任何 Hibernate 相关信息记录日志(信息量较大,但对查错非常有帮助) |
在使用 Hibernate 开发应用程序时,你应当总是为 org.hibernate.SQL
开启 debug
级别的日志记录,或者开启 hibernate.show_sql
属性。
org.hibernate.cfg.NamingStrategy
接口允许你为数据库中的对象和 schema 元素指定一个“命名标准”。
你可能会提供一些通过 Java 标识生成数据库标识或将映射定义文件中"逻辑"表/列名处理成"物理"表/列名的规则。这个特性有助于减少冗长的映射定义文件,消除重复内容(如 TBL_
前缀)。Hibernate 使用的缺省策略是相当精简的。
在加入映射定义前,你可以调用 Configuration.setNamingStrategy()
指定一个不同的命名策略:
SessionFactory sf = new Configuration()
.setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
.addFile("Item.hbm.xml")
.addFile("Bid.hbm.xml")
.buildSessionFactory();
org.hibernate.cfg.ImprovedNamingStrategy
是一个内建的命名策略,对一些应用程序而言,可能是非常有用的起点。
You can configure the persister implementation used to persist your entities and collections:
-
by default, Hibernate uses persisters that make sense in a relational model and follow Java Persistence's specification
-
you can define a
PersisterClassProvider
implementation that provides the persister class used of a given entity or collection -
finally, you can override them on a per entity and collection basis in the mapping using
@Persister
or its XML equivalent
The latter in the list the higher in priority.
You can pass the PersisterClassProvider
instance to the Configuration
object.
SessionFactory sf = new Configuration()
.setPersisterClassProvider(customPersisterClassProvider)
.addAnnotatedClass(Order.class)
.buildSessionFactory();
The persister class provider methods, when returning a non null persister class, override the default Hibernate persisters. The entity name or the collection role are passed to the methods. It is a nice way to centralize the overriding logic of the persisters instead of spreading them on each entity or collection mapping.
另一个配置方法是在 hibernate.cfg.xml
文件中指定一套完整的配置。这个文件可以当成 hibernate.properties
的替代。若两个文件同时存在,它将覆盖前者的属性。
XML 配置文件被默认是放在 CLASSPATH
的根目录下。下面是一个例子:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory
name="java:hibernate/SessionFactory">
<!-- properties -->
<property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">false</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="jta.UserTransaction">java:comp/UserTransaction</property>
<!-- mapping files -->
<mapping resource="org/hibernate/auction/Item.hbm.xml"/>
<mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
<!-- cache settings -->
<class-cache class="org.hibernate.auction.Item" usage="read-write"/>
<class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
<collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
</session-factory>
</hibernate-configuration>
如你所见,这个方法优势在于,在配置文件中指出了映射定义文件的名字。一旦你需要调整 Hibernate 的缓存,hibernate.cfg.xml
也是更方便。注意,使用 hibernate.properties
还是 hibernate.cfg.xml
完全是由你来决定,除了上面提到的 XML 语法的优势之外,两者是等价的。
使用 XML 配置,使得启动 Hibernate 变的异常简单:
SessionFactory sf = new Configuration (). configure (). buildSessionFactory ();
你可以使用如下代码来添加一个不同的 XML 配置文件:
SessionFactory sf = new Configuration()
.configure("catdb.cfg.xml")
.buildSessionFactory();
针对 J2EE 体系,Hibernate 有如下几个集成的方面:
-
容器管理的数据源(Container-managed datasources): Hibernate 能使用通过容器管理,并由 JNDI 提供的 JDBC 连接。通常,特别是当处理多个数据源的分布式事务的时候,由一个 JTA 兼容的
TransactionManager
和一个ResourceManager
来处理事务管理(CMT,容器管理的事务)。当然你可以通过 编程方式来划分事务边界(BMT,Bean 管理的事务)。或者为了代码的可移植性,你也也许会想使用可选的 HibernateTransaction
API。
-
自动 JNDI 绑定:Hibernate 可以在启动后将
SessionFactory
绑定到 JNDI。
-
JTA Session 绑定: Hibernate
Session
可以自动绑定到 JTA 事务作用的范围。只需简单地从 JNDI 查找SessionFactory
并获得当前的Session
。当 JTA 事务完成时,让 Hibernate来处理Session
的清洗(flush)与关闭。事务的划分可以是声明式的(CMT),也可以是编程式的(BMT/UserTransaction)。
-
JMX 部署: 如果你使用支持 JMX 应用程序服务器(如,JBoss AS),那么你可以选择将 Hibernate 部署成托管 MBean。这将为你省去一行从
Configuration
构建SessionFactory
的启动代码。容器将启动你的HibernateService
,并完美地处理好服务间的依赖关系(在 Hibernate 启动前,数据源必须是可用的,等等)。
如果应用程序服务器抛出 "connection containment" 异常,根据你的环境,也许该将配置属性 hibernate.connection.release_mode
设为 after_statement
。
在你的架构中,Hibernate 的 Session
API 是独立于任何事务分界系统的。如果你让 Hibernate 通过连接池直接使用 JDBC,你需要调用 JDBC API 来打开和关闭你的事务。如果你运行在 J2EE 应用程序服务器中,你也许想用 Bean 管理的事务并在需要的时候调用 JTA API 和 UserTransaction
。
为了让你的代码在两种(或其他)环境中可以移植,我们建议使用可选的 Hibernate Transaction
API,它包装并隐藏了底层系统。你必须通过设置 Hibernate 配置属性 hibernate.transaction.factory_class
来指定一个 Transaction
实例的工厂类。
有三个标准(内建)的选择:
-
org.hibernate.transaction.JDBCTransactionFactory
-
委托给数据库(JDBC)事务(默认)
-
org.hibernate.transaction.JTATransactionFactory
-
如果在上下文环境中存在运行着的事务(如,EJB 会话 Bean 的方法),则委托给容器管理的事务。否则,将启动一个新的事务,并使用 Bean 管理的事务。
-
org.hibernate.transaction.CMTTransactionFactory
-
委托给容器管理的 JTA 事务
你也可以定义属于你自己的事务策略(如,针对 CORBA 的事务服务)。
Hibernate 的一些特性(比如二级缓存,Contextual Sessions with JTA 等等)需要访问在托管环境中的 JTA TransactionManager
。由于 J2EE 没有标准化一个单一的机制,Hibernate 在应用程序服务器中,你必须指定 Hibernate 如何获得 TransactionManager
的引用:
表 3.10. JTA TransactionManagers
Transaction 工厂类 | 应用程序服务器 |
---|---|
org.hibernate.transaction.JBossTransactionManagerLookup
|
JBoss AS |
org.hibernate.transaction.WeblogicTransactionManagerLookup
|
Weblogic |
org.hibernate.transaction.WebSphereTransactionManagerLookup
|
WebSphere |
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
|
WebSphere 6 |
org.hibernate.transaction.OrionTransactionManagerLookup
|
Orion |
org.hibernate.transaction.ResinTransactionManagerLookup
|
Resin |
org.hibernate.transaction.JOTMTransactionManagerLookup
|
JOTM |
org.hibernate.transaction.JOnASTransactionManagerLookup
|
JOnAS |
org.hibernate.transaction.JRun4TransactionManagerLookup
|
JRun4 |
org.hibernate.transaction.BESTransactionManagerLookup
|
Borland ES |
org.hibernate.transaction.JBossTSStandaloneTransactionManagerLookup
|
JBoss TS used standalone (ie. outside JBoss AS and a JNDI environment generally). Known to work for org.jboss.jbossts:jbossjta:4.11.0.Final |
与 JNDI 绑定的 Hibernate 的 SessionFactory
能简化工厂的查询,简化创建新的 Session
。需要注意的是这与 JNDI 绑定 Datasource
没有关系,它们只是恰巧用了相同的注册表。
如果你希望将 SessionFactory
绑定到一个 JNDI 的名字空间,用属性 hibernate.session_factory_name
指定一个名字(如,java:hibernate/SessionFactory
)。如果不设置这个属性,SessionFactory
将不会被绑定到 JNDI 中(在以只读 JNDI 为默认实现的环境中,这个设置尤其有用,如 Tomcat)。
在将 SessionFactory
绑定至 JNDI 时,Hibernate 将使用 hibernate.jndi.url
,和 hibernate.jndi.class
的值来实例化初始环境(initial context)。如果它们没有被指定,将使用默认的 InitialContext
。
在你调用 cfg.buildSessionFactory()
后,Hibernate 会自动将 SessionFactory
注册到 JNDI。这意味这你至少需要在你应用程序的启动代码(或工具类)中完成这个调用,除非你使用 HibernateService
来做 JMX 部署(见后面讨论)。
假若你使用 JNDI SessionFactory
,EJB 或者任何其它类都可以从 JNDI 中找到此 SessionFactory
。
It is recommended that you bind the SessionFactory
to JNDI in a managed environment and use a static
singleton otherwise. To shield your application code from these details, we also recommend to hide the actual lookup code for a SessionFactory
in a helper class, such as HibernateUtil.getSessionFactory()
. Note that such a class is also a convenient way to startup Hibernate—see chapter 1.
The easiest way to handle Sessions
and transactions is Hibernate's automatic "current" Session
management. For a discussion of contextual sessions see 第 2.3 节 “上下文相关的会话(Contextual Session)”. Using the "jta"
session context, if there is no Hibernate Session
associated with the current JTA transaction, one will be started and associated with that JTA transaction the first time you call sessionFactory.getCurrentSession()
. The Session
s retrieved via getCurrentSession()
in the "jta"
context are set to automatically flush before the transaction completes, close after the transaction completes, and aggressively release JDBC connections after each statement. This allows the Session
s to be managed by the life cycle of the JTA transaction to which it is associated, keeping user code clean of such management concerns. Your code can either use JTA programmatically through UserTransaction
, or (recommended for portable code) use the Hibernate Transaction
API to set transaction boundaries. If you run in an EJB container, declarative transaction demarcation with CMT is preferred.
为了将 SessionFactory
注册到 JNDI 中,cfg.buildSessionFactory()
这行代码仍需在某处被执行。你可在一个 static
初始化块(像 HibernateUtil
中的那样)中执行它或将 Hibernate 部署为一个托管的服务。
为了部署在一个支持 JMX 的应用程序服务器上,Hibernate 和 org.hibernate.jmx.HibernateService
一同分发,如 Jboss AS。 实际的部署和配置是由应用程序服务器提供者指定的。这里是 JBoss 4.0.x 的 jboss-service.xml
样例:
<?xml version="1.0"?>
<server>
<mbean code="org.hibernate.jmx.HibernateService"
name="jboss.jca:service=HibernateFactory,name=HibernateFactory">
<!-- Required services -->
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
<!-- Bind the Hibernate service to JNDI -->
<attribute name="JndiName">java:/hibernate/SessionFactory</attribute>
<!-- Datasource settings -->
<attribute name="Datasource">java:HsqlDS</attribute>
<attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
<!-- Transaction integration -->
<attribute name="TransactionStrategy">
org.hibernate.transaction.JTATransactionFactory</attribute>
<attribute name="TransactionManagerLookupStrategy">
org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
<attribute name="FlushBeforeCompletionEnabled">true</attribute>
<attribute name="AutoCloseSessionEnabled">true</attribute>
<!-- Fetching options -->
<attribute name="MaximumFetchDepth">5</attribute>
<!-- Second-level caching -->
<attribute name="SecondLevelCacheEnabled">true</attribute>
<attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
<attribute name="QueryCacheEnabled">true</attribute>
<!-- Logging -->
<attribute name="ShowSqlEnabled">true</attribute>
<!-- Mapping files -->
<attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>
</mbean>
</server>
这个文件是部署在 META-INF
目录下的,并会被打包到以 .sar
(service archive)为扩展名的 JAR 文件中。同时,你需要将 Hibernate、它所需要的第三方库、你编译好的持久化类以及你的映射定义文件打包进同一个文档。你的企业 Bean(一般为会话 Bean)可能会被打包成它们自己的 JAR 文件,但你也许会将 EJB JAR 文件一同包含进能独立(热)部署的主服务文档。参考 JBoss AS 文档以了解更多的 JMX服务与 EJB 部署的信息。
版权 © 2004 Red Hat, Inc.