第 4 章 配置
由于Hibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都 有比较直观的默认值, 并有随Hibernate一同分发的配置样例hibernate.properties (位于etc/)来展示各种配置选项. 所需做的仅仅是将这个样例文件复制到类路径 (classpath)下做一些自定义的修改.
一个org.hibernate.cfg.Configuration实例代表了一个应用程序中Java类型 到SQL数据库映射的完整集合. Configuration被用来构建一个(不可变的 (immutable))SessionFactory. 映射定义则由不同的XML映射定义文件编译而来.
你可以直接实例化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).
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> (稍后讨论).
如果想尽快体验Hbernate, hibernate.properties是最简单的方式.
Configuration实例是一个启动期间(startup-time)的对象, 一旦SessionFactory创建完成它就被丢弃了.
当所有映射定义被Configuration解析后, 应用程序必须获得一个用于构造Session实例的工厂. 这个工厂将被应用程序的所有线程共享:
SessionFactory sessions = cfg.buildSessionFactory();
Hibernate允许你的应用程序创建多个SessionFactory实例. 这对 使用多个数据库的应用来说很有用.
通常你希望SessionFactory来为你创建和缓存(pool)JDBC连接. 如果你采用这种方式, 只需要如下例所示那样,打开一个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连接 :
属性名 |
用途 |
hibernate.connection.driver_class |
jdbc驱动类 |
hibernate.connection.url |
jdbc URL |
hibernate.connection.username |
数据库用户 |
hibernate.connection.password |
数据库用户密码 |
hibernate.connection.pool_size |
连接池容量上限数目 |
但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处获得连接,你至少需要设置下列属性中的一个:
属性名 |
用途 |
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来设置, 而不能用上面描述的其他方法来设置.
属性名 |
用途 |
hibernate.dialect |
一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL. 取值 full.classname.of.Dialect |
hibernate.show_sql |
输出所有SQL语句到控制台. 取值 true | false |
hibernate.default_schema |
在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上. 取值 SCHEMA_NAME |
hibernate.default_catalog |
在生成的SQL中, 将给定的catalog附加于没全限定名的表名上. 取值 CATALOG_NAME |
hibernate.session_factory_name |
SessionFactory创建后,将自动使用这个名字绑定到JNDI中. 取值 jndi/composite/name |
hibernate.max_fetch_depth |
为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取. 取值 建议在0到3之间取值 |
hibernate.default_batch_fetch_size |
为Hibernate关联的批量抓取设置默认数量. 取值 建议的取值为4, 8, 和16 |
hibernate.default_entity_mode |
为由这个SessionFactory打开的所有Session指定默认的实体表现模式. 取值 dynamic-map, dom4j, pojo |
hibernate.order_updates |
强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。 取值 true | false |
hibernate.generate_statistics |
如果开启, Hibernate将收集有助于性能调节的统计数据. 取值 true | false |
hibernate.use_identifer_rollback |
如果开启, 在对象被删除时生成的标识属性将被重设为默认值. 取值 true | false |
hibernate.use_sql_comments |
如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为false. 取值 true | false |
表4.4. Hibernate JDBC和连接(connection)属性
属性名 |
用途 |
hibernate.jdbc.fetch_size |
非零值,指定JDBC抓取数量的大小 (调用Statement.setFetchSize()). |
hibernate.jdbc.batch_size |
非零值,允许Hibernate使用JDBC2的批量更新. 取值 建议取5到30之间的值 |
hibernate.jdbc.batch_versioned_data |
如果你想让你的JDBC驱动从executeBatch()返回正确的行计数 , 那么将此属性设为true(开启这个选项通常是安全的). 同时,Hibernate将为自动版本化的数据使用批量DML. 默认值为false. eg. true | false |
hibernate.jdbc.factory_class |
选择一个自定义的Batcher. 多数应用程序不需要这个配置属性. eg. classname.of.Batcher |
hibernate.jdbc.use_scrollable_resultset |
允许Hibernate使用JDBC2的可滚动结果集. 只有在使用用户提供的JDBC连接时,这个选项才是必要的, 否则Hibernate会使用连接的元数据. 取值 true | false |
hibernate.jdbc.use_streams_for_binary |
在JDBC读写binary (二进制)或serializable (可序列化) 的类型时使用流(stream)(系统级属性). 取值 true | false |
hibernate.jdbc.use_get_generated_keys |
在数据插入数据库之后,允许使用JDBC3 PreparedStatement.getGeneratedKeys() 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标 识生成器时遇到问题,请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力. 取值 true|false |
hibernate.connection.provider_class |
自定义ConnectionProvider的类名, 此类用来向Hibernate提供JDBC连接. 取值 classname.of.ConnectionProvider |
hibernate.connection.isolation |
设置JDBC事务隔离级别. 查看java.sql.Connection来了解各个值的具体意义, 但请注意多数数据库都不支持所有的隔离级别. 取值 1, 2, 4, 8 |
hibernate.connection.autocommit |
允许被缓存的JDBC连接开启自动提交(autocommit) (不建议). 取值 true | false |
hibernate.connection.release_mode |
指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接. 对于应用程序服务器的JTA数据源, 你应当使用after_statement, 这样在每次JDBC调用后,都会主动的释放连接. 对于非JTA的连接, 使用after_transaction在每个事务结束时释放连接是合理的. auto将为JTA和CMT事务策略选择after_statement, 为JDBC事务策略选择after_transaction. 取值 on_close | after_transaction | after_statement | auto |
hibernate.connection.<propertyName> |
将JDBC属性propertyName传递到DriverManager.getConnection()中去. |
hibernate.jndi.<propertyName> |
将属性propertyName传递到JNDI InitialContextFactory中去. |
属性名 |
用途 |
hibernate.cache.provider_class |
自定义的CacheProvider的类名. 取值 classname.of.CacheProvider |
hibernate.cache.use_minimal_puts |
以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中,这个设置对的集群缓存非常有用, 对集群缓存的实现而言,默认是开启的. 取值 true|false |
hibernate.cache.use_query_cache |
允许查询缓存, 个别查询仍然需要被设置为可缓存的. 取值 true|false |
hibernate.cache.use_second_level_cache |
能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定<cache>的类,会默认开启二级缓存. 取值 true|false |
hibernate.cache.query_cache_factory |
自定义的实现QueryCache接口的类名, 默认为内建的StandardQueryCache. 取值 classname.of.QueryCache |
hibernate.cache.region_prefix |
二级缓存区域名的前缀. 取值 prefix |
hibernate.cache.use_structured_entries |
强制Hibernate以更人性化的格式将数据存入二级缓存. 取值 true|false |
属性名 |
用途 |
hibernate.transaction.factory_class |
一个TransactionFactory的类名, 用于Hibernate Transaction API (默认为JDBCTransactionFactory). 取值 classname.of.TransactionFactory |
jta.UserTransaction |
一个JNDI名字,被JTATransactionFactory用来从应用服务器获取JTA UserTransaction. 取值 jndi/composite/name |
hibernate.transaction.manager_lookup_class |
一个TransactionManagerLookup的类名 - 当使用JVM级缓存,或在JTA环境中使用hilo生成器的时候需要该类. 取值 classname.of.TransactionManagerLookup |
hibernate.transaction.flush_before_completion |
如果开启, session在事务完成后将被自动清洗(flush). (在Hibernate和CMT一起使用时很有用.) 取值 true | false |
hibernate.transaction.auto_close_session |
如果开启, session在事务完成后将被自动关闭. (在Hibernate和CMT一起使用时很有用.) 取值 true | false |
属性名 |
用途 |
hibernate.query.factory_class |
选择HQL解析器的实现. 取值 org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory |
hibernate.query.substitutions |
将Hibernate查询中的符号映射到SQL查询中的符号 (符号可能是函数名或常量名字). 取值 hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC |
hibernate.hbm2ddl.auto |
在SessionFactory创建时,自动将数据库schema的DDL导出到数据库. 使用 create-drop时,在显式关闭SessionFactory时,将drop掉数据库schema. 取值 update | create | create-drop |
hibernate.cglib.use_reflection_optimizer |
开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用. 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在hibernate.cfg.xml中设置此属性. 取值 true | false |
你应当总是为你的数据库属性hibernate.dialect设置正确的 org.hibernate.dialect.Dialect子类. 如果你指定一种方言,Hibernate将为上面列出的一些属性使用合理的默认值, 为你省去了手工指定它们的功夫.
表4.8.Hibernate SQL方言 (hibernate.dialect)
RDBMS |
方言 |
DB2 |
org.hibernate.dialect.DB2Dialect |
DB2 AS/400 |
org.hibernate.dialect.DB2400Dialect |
DB2 OS390 |
org.hibernate.dialect.DB2390Dialect |
PostgreSQL |
org.hibernate.dialect.PostgreSQLDialect |
MySQL |
org.hibernate.dialect.MySQLDialect |
MySQL with InnoDB |
org.hibernate.dialect.MySQLInnoDBDialect |
MySQL with MyISAM |
org.hibernate.dialect.MySQLMyISAMDialect |
Oracle (any version) |
org.hibernate.dialect.OracleDialect |
Oracle 9i/10g |
org.hibernate.dialect.Oracle9Dialect |
Sybase |
org.hibernate.dialect.SybaseDialect |
Sybase Anywhere |
org.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server |
org.hibernate.dialect.SQLServerDialect |
SAP DB |
org.hibernate.dialect.SAPDBDialect |
Informix |
org.hibernate.dialect.InformixDialect |
HypersonicSQL |
org.hibernate.dialect.HSQLDialect |
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 |
4.4.2. 外连接抓取(Outer Join Fetching)
如果你的数据库支持ANSI, Oracle或Sybase风格的外连接, 外连接抓取常能通过限制往返数据库次数 (更多的工作交由数据库自己来完成)来提高效率. 外连接允许在单个SELECTSQL语句中, 通过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"来映射.
参见第20.1节 “ 抓取策略(Fetching strategies) ”获得更多信息.
Oracle限制那些通过JDBC驱动传输的字节数组的数目. 如果你希望使用二进值 (binary)或 可序列化的 (serializable)类型的大对象, 你应该开启 hibernate.jdbc.use_streams_for_binary属性. 这是系统级属性.
以hibernate.cache为前缀的属性允许你在Hibernate中,使用进程或群集范围内的二级缓存系统. 参见第20.2节 “二级缓存(The Second Level Cache) ”获取更多的详情.
你可以使用hibernate.query.substitutions在Hibernate中定义新的查询符号. 例如:
hibernate.query.substitutions true=1, false=0
将导致符号true和false在生成的SQL中被翻译成整数常量.
hibernate.query.substitutions toLowercase=LOWER
将允许你重命名SQL中的LOWER函数.
4.4.6. Hibernate的统计(statistics)机制
如果你开启hibernate.generate_statistics, 那么当你通过 SessionFactory.getStatistics()调整正在运行的系统时,Hibernate将导出大量有用的数据. Hibernate甚至能被配置成通过JMX导出这些统计信息. 参考org.hibernate.stats中接口的Javadoc,以获得更多信息.
Hibernate使用Apache commons-logging来为各种事件记录日志.
commons-logging将直接输出到Apache Log4j(如果在类路径中包括log4j.jar)或 JDK1.4 logging (如果运行在JDK1.4或以上的环境下). 你可以从http://jakarta.apache.org 下载Log4j.要使用Log4j,你需要将log4j.properties文件放置在类路径下, 随Hibernate 一同分发的样例属性文件在src/目录下.
我们强烈建议你熟悉一下Hibernate的日志消息. 在不失可读性的前提下, 我们做了很多工作,使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 |
为HQL和SQL的自动状态转换和其他关于查询解析的信息记录日志 |
org.hibernate.secure |
为JAAS认证请求做日志 |
org.hibernate |
为任何Hibernate相关信息做日志 (信息量较大, 但对查错非常有帮助) |
在使用Hibernate开发应用程序时, 你应当总是为org.hibernate.SQL 开启debug级别的日志记录,或者开启hibernate.show_sql属性来代替它。.
org.hibernate.cfg.NamingStrategy接口允许你为数据库中的对象和schema 元素指定一个“命名标准”.
你可能会提供一些通过Java标识生成数据库标识或将映射定义文件中"逻辑"表/列名处理成"物理"表/列名的规则. 这个特性有助于减少冗长的映射定义文件.
在加入映射定义前,你可以调用Configuration.setNamingStrategy()指定一个不同的命名策略:
SessionFactory sf = new Configuration()
.setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
.addFile("Item.hbm.xml")
.addFile("Bid.hbm.xml")
.buildSessionFactory();
org.hibernate.cfg.ImprovedNamingStrategy是一个内建的命名策略, 对 一些应用程序而言,可能是非常有用的起点.
另一个配置方法是在hibernate.cfg.xml文件中指定一套完整的配置. 这个文件可以当成hibernate.properties的替代。 若两个文件同时存在,它将重载前者的属性.
XML配置文件被默认是放在CLASSPATH的根目录下. 这是一个例子:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/HibernateConfiguration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 以/jndi/name绑定到JNDI的SessionFactory实例 -->
<session-factory
name="java:hibernate/SessionFactory">
<!-- 属性 -->
<propertyname="connection.datasource">java:/comp/env/jdbc/MyDB</property>
<propertyname="dialect">org.hibernate.dialect.MySQLDialect</property>
<propertyname="show_sql">false</property>
<propertyname="transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<propertyname="jta.UserTransaction">java:comp/UserTransaction</property>
<!-- 映射定义文件 -->
<mappingresource="org/hibernate/auction/Item.hbm.xml"/>
<mappingresource="org/hibernate/auction/Bid.hbm.xml"/>
<!-- 缓存设置 -->
<class-cacheclass="org.hibernate.auction.Item" usage="read-write"/>
<class-cacheclass="org.hibernate.auction.Bid" usage="read-only"/>
<collection-cacheclass="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管理的事务). 或者为了代码的可移植性,你也也许会想使用可选的 Hibernate Transaction API.
·自动JNDI绑定:Hibernate可以在启动后将 SessionFactory绑定到JNDI.
·JTASession绑定: 如果使用EJB, Hibernate Session 可以自动绑定到JTA事务作用的范围. 只需简单地从JNDI查找SessionFactory并获得当前的Session. 当JTA事务完成时, 让Hibernate来处理 Session的清洗(flush)与关闭. 在EJB的部署描述符中事务边界是声明式的.
·JMX部署: 如果你使用支持JMX应用程序服务器(如, JBossAS), 那么你可以选择将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的一些特性 (即二级缓存, JTA与Session的自动绑定等等)需要访问在托管环境中的JTA TransactionManager. 由于J2EE没有标准化一个单一的机制,Hibernate在应用程序服务器中,你必须指定Hibernate如何获得TransactionManager的引用:
Transaction工厂类 |
应用程序服务器 |
org.hibernate.transaction.JBossTransactionManagerLookup |
JBoss |
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 |
与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. 请注意, 如果你使用第一章中介绍的帮助类HibernateUtil - 类似Singleton(单实例)注册表, 那么这里的启动代码不是必要的. 但HibernateUtil更多被使用在非托管环境中.
在非托管环境中,我们建议:HibernateUtil和静态SessionFactory一起工作, 由ThreadLocal管理Hibernate Session。 由于一些EJB可能会运行在同一个事务但不同线程的环境中, 所以这个方法不能照搬到EJB环境中.我们建议在托管环境中,将SessionFactory绑定到JNDI上.
请使用SessionFactory的getCurrentSession()方法来代替 直接使用ThreadLocal去获得Hibernate Session. 如果在当前JTA事务中没有Hibernate Session, 将会启动一个并将它关联到事务中. 对于使用getCurrentSession()获得的每个Session而言, hibernate.transaction.flush_before_completion 和hibernate.transaction.auto_close_session这两个配置选项会自动设置, 因此在容器结束JTA事务时,这些Session会被自动清洗(flush)并关闭.
例如,如果你使用DAO模式来编写你的持久层, 那么在需要时,所有DAO将查找SessionFactory并打开"当前"Session.没有必要在控制代码和DAO代码间传递SessionFactory或Session的实例.
为了将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">
<!-- 必须的服务 -->
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>
<!-- 将Hibernate服务绑定到JNDI-->
<attributename="JndiName">java:/hibernate/SessionFactory</attribute>
<!-- 数据源设置 -->
<attributename="Datasource">java:HsqlDS</attribute>
<attributename="Dialect">org.hibernate.dialect.HSQLDialect</attribute>
<!-- 事务集成 -->
<attributename="TransactionStrategy">
org.hibernate.transaction.JTATransactionFactory</attribute>
<attributename="TransactionManagerLookupStrategy">
org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
<attributename="FlushBeforeCompletionEnabled">true</attribute>
<attributename="AutoCloseSessionEnabled">true</attribute>
<!-- 抓取选项 -->
<attributename="MaximumFetchDepth">5</attribute>
<!-- 二级缓存 -->
<attributename="SecondLevelCacheEnabled">true</attribute>
<attributename="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
<attributename="QueryCacheEnabled">true</attribute>
<!-- 日志 -->
<attributename="ShowSqlEnabled">true</attribute>
<!-- 映射定义文件 -->
<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部署的信息.
第3章体系结构(Architecture) |
第5章持久化类(Persistent Classes) |
相关推荐
【大数据运维技术第4章 Hadoop文件参数配置】 在大数据领域,Hadoop是一个核心的开源框架,主要用于处理和存储大规模数据。本章主要探讨的是Hadoop的文件参数配置,这对于确保Hadoop集群的稳定运行至关重要。以下是...
第4章 配置、error日志和请求上下文 111 第5章 访问第三方服务 154 第6章 开发一个简单的过滤模块 192 第7章 Nginx提供的高级数据结构 207 第三部分 深入Nginx 第8章 Nginx基础架构 248 第9章 事件模块 285 ...
#### 第4章 配置 VLAN **4.1 简介** - 介绍 VLAN 的概念及其在企业网络中的作用。 **4.2 可支持的 VLAN** - 支持 VLAN ID 从 1 到 4094,最多支持 1005 个 VLAN。 **4.3 配置正常范围的 VLAN** - **4.3.1 删除...
第4章 DHCP服务器配置与管理
#### 第4章 配置 VLAN ##### 4.1 简介 VLAN(虚拟局域网)技术用于分割网络,提高安全性并优化网络性能。思科 3560 支持高达 1005 个 VLAN,每个 VLAN 的 ID 从 1 到 4094。 ##### 4.2 可支持的 VLAN - **配置...
教程名称:Cisco网络工程师和网络安全课程PPT课程目录:【】第10章 IPv6【】第11章 广域网【】第1章 计算机网络详解v2【】第2章 TCPIP协议和网络安全【】第3章 IP地址和子网划分【】第4章 配置Cisco网络设备【】第5...
4. 实验过程 实验过程可以分为六个任务: * 实验任务一:在 Master 节点上安装 Hadoop * 实验任务二:配置 hdfs-site.xml 文件参数 * 实验任务三:配置 core-site.xml 文件参数 * 实验任务四:配置 mapred-site....
#### 第4章 配置VLAN - **4.1 简介** - VLAN(Virtual Local Area Network)是一种将物理网络划分成多个逻辑网络的技术,可以有效隔离广播域,提高网络安全性和性能。 - **4.2 可支持的VLAN** - Cisco 3560 支持...
第4章 Nginx与PHP(FastCGI)的安装、配置与优化.pdf 第5章 Nginx与JSP、ASP.NET、Perl的安装与配置.pdf 第6章 Nginx HTTP负载均衡和反向代理的配置与优化.pdf 第7章 Nginx的Rewrite规则与实例.pdf 第8章 Nginx模块...
#### 第4章 配置 VLAN **4.1 简介** VLAN 技术可以将一个物理局域网划分为多个逻辑局域网,实现更细粒度的管理和隔离。 **4.2 可支持的 VLAN** Catalyst 3560 支持多达 1005 个 VLAN,VLAN ID 范围从 1 到 4094...
第4章服务器系统安全配置.pptx
#### 第4章 配置 Keepalived **4.1 文件目录调整** - 根据实际需求调整 Keepalived 配置文件的位置,通常位于 `/etc/keepalived/`。 **4.2 设置开机启动** - 将 Keepalived 设置为开机启动:`chkconfig ...
第4章 广域网接入配置指导 第5章 IP业务配置指导 第6章 IP路由配置指导 第7章 IP组播配置指导 第8章 IPv6配置指导 第9章 MPLS配置指导 第10章 ACL与QoS配置指导 第11章 安全特性配置指导 第12章 语音配置指导 第13章...
第4章 配置和优化SQL Server 2008 68 4.1 访问SQL Server的配置数据 69 4.1.1 使用系统目录和目录视图 70 4.1.2 使用系统存储过程 75 4.2 管理SQL Server配置选项的技巧 82 4.2.1 设置配置选项 82 ...
【第05章 配置symfony1】 在symfony框架中,配置是至关重要的,它允许开发者根据项目需求对框架进行个性化定制。本章主要探讨symfony的配置系统及其特性,包括YAML语法和symfony的配置惯例。 首先, symfony的配置...
第4章 配置X Window系统,版本11 23 4.1 X Window系统 23 4.2 建立XFree86系统 24 4.3 配置XFree86系统 25 4.3.1 XF86Config文件 27 4.3.2 使用XConfigurator 28 4.4 检查XF86Config文件 32 4.4.1 XF86Config Files...
### 哈工大DSP课件---第4章系统配置与中断 #### 一、系统配置与中断概述 本章内容主要围绕哈工大DSP课程中的第4章展开,涉及了系统配置寄存器和中断模块两个核心部分。在数字信号处理(DSP)领域,系统配置决定了DSP...
第4章 配置和优化SQL Server 2008 68 4.1 访问SQL Server的配置数据 69 4.1.1 使用系统目录和目录视图 70 4.1.2 使用系统存储过程 75 4.2 管理SQL Server配置选项的技巧 82 4.2.1 设置配置选项 82 ...
第4章 配置和优化SQL Server 2008 68 4.1 访问SQL Server的配置数据 69 4.1.1 使用系统目录和目录视图 70 4.1.2 使用系统存储过程 75 4.2 管理SQL Server配置选项的技巧 82 4.2.1 设置配置选项 82 ...