使用hibernate生成实体类新增时报错实体类不在sessionFactory的ClassMetaData集合中,该方法不可用

Spring3 整合Hibernate3.5 动态切换SessionFactory (切换数据库方言)
一、缘由上一篇文章Spring3 3 整合 Hibernate3、MyBatis3 2 配置多数据源 动态切换数据源 方法介绍到了怎么样在Sping、MyBatis、Hibernate整合的应用中动态切换DataSource数据源的方法,但最终遗留下一个问题
上一篇文章Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法介绍到了怎么样在Sping、MyBatis、Hibernate整合的应用中动态切换DataSource数据源的方法,但最终遗留下一个问题:不能切换方言。数据库方言可能在当前应用的架构中意义不是很大,但是如果单纯用MyBatis或Hibernate做数据库持久化操作,还是要处理这一问题。
那么下面将介绍怎么样动态切换SessionFactory,为什么要切换SessionFactory?
因为这里切换SessionFactory就可以实现多数据源和多个SessionFactory,每个SessionFactory有自己独立的数据库配置和SessionFactory的相关配置。我们的数据库方言就配置在SessionFactory这里,所以实现了切换SessionFactory也就实现了切换数据库方言的问题。这个主要是针对Hibernate来操作的,而MyBatis则需要动态切换SqlSessionFactory才行。
二、实现代码
1、定义全局切换SessionFactory的工具
package com.hoo.framework.spring.
* &b&function:&/b& 多数据源
* @author hoojo
* @createDate
上午11:36:57
* @file CustomerContextHolder.java
* @package com.hoo.framework.spring.support
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
public abstract class CustomerContextHolder {
public final static String SESSION_FACTORY_MYSQL = "";
public final static String SESSION_FACTORY_ORACLE = "oracle";
private static final ThreadLocal&String& contextHolder = new ThreadLocal&String&();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
public static String getCustomerType() {
return contextHolder.get();
public static void clearCustomerType() {
contextHolder.remove();
同样上面的静态变量和前一文章中介绍的一致,它需要和下面配置文件中的SessionFactory的key对应。
2、实现自己的SessionFactory
定义好接口
package com.hoo.framework.spring.support.
import org.hibernate.SessionF
* &b&function:&/b& 动态SessionFactory接口
* @author hoojo
* @createDate
下午03:29:52
* @file DynamicSessionFactory.java
* @package com.hoo.framework.spring.support.core
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
public interface DynamicSessionFactory extends SessionFactory {
public SessionFactory getHibernateSessionFactory();
package com.hoo.framework.spring.support.
import java.io.S
import java.sql.C
import java.util.M
import java.util.S
import javax.naming.NamingE
import javax.naming.R
import org.hibernate.C
import org.hibernate.HibernateE
import org.hibernate.I
import org.hibernate.SessionF
import org.hibernate.StatelessS
import org.hibernate.TypeH
import org.hibernate.classic.S
import org.hibernate.engine.FilterD
import org.hibernate.metadata.ClassM
import org.hibernate.metadata.CollectionM
import org.hibernate.stat.S
import com.hoo.framework.spring.support.CustomerContextH
* &b&function:&/b& 动态数据源实现
* @author hoojo
* @createDate
下午03:31:31
* @file DynamicSessionFactoryImpl.java
* @package com.hoo.framework.spring.support.core
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
@SuppressWarnings({ "unchecked", "deprecation" })
public class DynamicSessionFactoryImpl implements DynamicSessionFactory {
private static final long serialVersionUID = 7414885L;
private Map&Object, SessionFactory& targetSessionF
private SessionFactory defaultTargetSessionF
* @see com.hoo.framework.spring.support.core.DynamicSessionFactory#getHibernateSessionFactory()
* &b&function:&/b& 重写这个方法,这里最关键
* @author hoojo
* @createDate
上午10:45:25
public SessionFactory getHibernateSessionFactory() {
SessionFactory targetSessionFactory = targetSessionFactorys.get(CustomerContextHolder.getCustomerType());
if (targetSessionFactory != null) {
return targetSessionF
} else if (defaultTargetSessionFactory != null) {
return defaultTargetSessionF
public void close() throws HibernateException {
this.getHibernateSessionFactory().close();
public boolean containsFetchProfileDefinition(String s) {
return this.getHibernateSessionFactory().containsFetchProfileDefinition(s);
public void evict(Class clazz) throws HibernateException {
this.getHibernateSessionFactory().evict(clazz);
public void evict(Class clazz, Serializable serializable) throws HibernateException {
this.getHibernateSessionFactory().evict(clazz, serializable);
public void evictCollection(String s) throws HibernateException {
this.getHibernateSessionFactory().evictCollection(s);
public void evictCollection(String s, Serializable serializable) throws HibernateException {
this.getHibernateSessionFactory().evictCollection(s, serializable);
public void evictEntity(String entity) throws HibernateException {
this.getHibernateSessionFactory().evictEntity(entity);
public void evictEntity(String entity, Serializable serializable) throws HibernateException {
this.getHibernateSessionFactory().evictEntity(entity, serializable);
public void evictQueries() throws HibernateException {
this.getHibernateSessionFactory().evictQueries();
public void evictQueries(String queries) throws HibernateException {
this.getHibernateSessionFactory().evictQueries(queries);
public Map&String, ClassMetadata& getAllClassMetadata() {
return this.getHibernateSessionFactory().getAllClassMetadata();
public Map getAllCollectionMetadata() {
return this.getHibernateSessionFactory().getAllClassMetadata();
public Cache getCache() {
return this.getHibernateSessionFactory().getCache();
public ClassMetadata getClassMetadata(Class clazz) {
return this.getHibernateSessionFactory().getClassMetadata(clazz);
public ClassMetadata getClassMetadata(String classMetadata) {
return this.getHibernateSessionFactory().getClassMetadata(classMetadata);
public CollectionMetadata getCollectionMetadata(String collectionMetadata) {
return this.getHibernateSessionFactory().getCollectionMetadata(collectionMetadata);
public Session getCurrentSession() throws HibernateException {
return this.getHibernateSessionFactory().getCurrentSession();
public Set getDefinedFilterNames() {
return this.getHibernateSessionFactory().getDefinedFilterNames();
public FilterDefinition getFilterDefinition(String definition) throws HibernateException {
return this.getHibernateSessionFactory().getFilterDefinition(definition);
public Statistics getStatistics() {
return this.getHibernateSessionFactory().getStatistics();
public TypeHelper getTypeHelper() {
return this.getHibernateSessionFactory().getTypeHelper();
public boolean isClosed() {
return this.getHibernateSessionFactory().isClosed();
public Session openSession() throws HibernateException {
return this.getHibernateSessionFactory().openSession();
public Session openSession(Interceptor interceptor) throws HibernateException {
return this.getHibernateSessionFactory().openSession(interceptor);
public Session openSession(Connection connection) {
return this.getHibernateSessionFactory().openSession(connection);
public Session openSession(Connection connection, Interceptor interceptor) {
return this.getHibernateSessionFactory().openSession(connection, interceptor);
public StatelessSession openStatelessSession() {
return this.getHibernateSessionFactory().openStatelessSession();
public StatelessSession openStatelessSession(Connection connection) {
return this.getHibernateSessionFactory().openStatelessSession(connection);
public Reference getReference() throws NamingException {
return this.getHibernateSessionFactory().getReference();
public void setTargetSessionFactorys(Map&Object, SessionFactory& targetSessionFactorys) {
this.targetSessionFactorys = targetSessionF
public void setDefaultTargetSessionFactory(SessionFactory defaultTargetSessionFactory) {
this.defaultTargetSessionFactory = defaultTargetSessionF
上面最重要的就是getHibernateSessionFactory重写这个方法,其他方法和原来实现的无异。重写这个方法后利用CustomerContextHolder动态设置SessionFactory类型就可以动态的切换SessionFactory。
3、动态的事务管理器,因为我们这里是动态切换SessionFactory,所以事务这块也需要动态切换SessionFactory来完成事务的操作。
package com.hoo.framework.spring.support.
import javax.sql.DataS
import org.hibernate.SessionF
import org.springframework.orm.hibernate3.HibernateTransactionM
import org.springframework.orm.hibernate3.SessionFactoryU
import com.hoo.framework.spring.support.core.DynamicSessionF
* &b&function:&/b& 重写HibernateTransactionManager事务管理器,实现自己的动态的事务管理器
* @author hoojo
* @createDate
下午03:54:02
* @file DynamicTransactionManager.java
* @package com.hoo.framework.spring.support.tx
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
public class DynamicTransactionManager extends HibernateTransactionManager {
private static final long serialVersionUID = -6819154L;
* @see org.springframework.orm.hibernate4.HibernateTransactionManager#getDataSource()
* &b&function:&/b& 重写
* @author hoojo
* @createDate
下午03:55:24
public DataSource getDataSource() {
return SessionFactoryUtils.getDataSource(getSessionFactory());
* @see org.springframework.orm.hibernate4.HibernateTransactionManager#getSessionFactory()
* &b&function:&/b& 重写
* @author hoojo
* @createDate
下午03:55:24
public SessionFactory getSessionFactory() {
DynamicSessionFactory dynamicSessionFactory = (DynamicSessionFactory) super.getSessionFactory();
SessionFactory hibernateSessionFactory = dynamicSessionFactory.getHibernateSessionFactory();
return hibernateSessionF
这里主要重写getDataSource()/getSessionFactory()这两个方法,getSessionFactory方法是利用我们上面定义的接口来动态获取我们在上下文(CustomerContextHolder)中定义切换的SessionFactory对象。而getDataSource则是获得动态SessionFactory的DataSource,这里也不难理解。
4、至此,重写的接口和实现都完成,下面开始配置相关的代码
&?xml version="1.0" encoding="UTF-8"?&
&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "&
&!-- 配置c3p0数据源 --&
&bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"&
&property name="driverClass" value="${datasource.driver}"/&
&property name="jdbcUrl" value="${datasource.url}"/&
&property name="user" value="${datasource.username}"/&
&property name="password" value="${datasource.password}"/&
&property name="acquireIncrement" value="${c3p0.acquireIncrement}"/&
&property name="initialPoolSize" value="${c3p0.initialPoolSize}"/&
&property name="minPoolSize" value="${c3p0.minPoolSize}"/&
&property name="maxPoolSize" value="${c3p0.maxPoolSize}"/&
&property name="maxIdleTime" value="${c3p0.maxIdleTime}"/&
&property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/&
&property name="maxStatements" value="${c3p0.maxStatements}"/&
&property name="numHelperThreads" value="${c3p0.numHelperThreads}"/&
&property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/&
&property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/&
&bean id="dataSourceMySQL" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"&
&property name="driverClass" value="com.mysql.jdbc.Driver"/&
&property name="jdbcUrl" value="jdbc:mysql://172.31.108.178:3306/world?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"/&
&property name="user" value="root"/&
&property name="password" value="jp2011"/&
&property name="acquireIncrement" value="${c3p0.acquireIncrement}"/&
&property name="initialPoolSize" value="${c3p0.initialPoolSize}"/&
&property name="minPoolSize" value="${c3p0.minPoolSize}"/&
&property name="maxPoolSize" value="${c3p0.maxPoolSize}"/&
&property name="maxIdleTime" value="${c3p0.maxIdleTime}"/&
&property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/&
&property name="maxStatements" value="${c3p0.maxStatements}"/&
&property name="numHelperThreads" value="${c3p0.numHelperThreads}"/&
&property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/&
&property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/&
&!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 --&
&bean id="mySQLSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&
&property name="dataSource" ref="dataSourceMySQL"/&
&property name="packagesToScan" value="com.hoo.**.mysqlentity"/&
&property name="annotatedClasses"&
&value&com.hoo.common.entity.IDGenerator&/value&
&/property&
&property name="hibernateProperties"&
&prop key="hibernate.dialect"&org.hibernate.dialect.MySQLDialect&/prop&
&!-- 链接释放策略 on_close | after_transaction | after_statement | auto
&prop key="hibernate.connection.release_mode"&after_transaction&/prop&
&prop key="hibernate.show_sql"&true&/prop&
&prop key="hibernate.format_sql"&true&/prop&
&/property&
&!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 --&
&bean id="oracleSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&
&property name="dataSource" ref="dataSourceOracle"/&
&property name="packagesToScan" value="com.hoo.**.entity"/&
&property name="hibernateProperties"&
&prop key="hibernate.dialect"&org.hibernate.dialect.OracleDialect&/prop&
&prop key="hibernate.connection.release_mode"&after_transaction&/prop&
&prop key="hibernate.show_sql"&true&/prop&
&prop key="hibernate.format_sql"&true&/prop&
&!--prop key="hibernate.hbm2ddl.auto"&update&/prop--&
&/property&
&!-- 动态SessionFactory --&
&bean id="sessionFactory" class="com.hoo.framework.spring.support.core.DynamicSessionFactoryImpl"&
&property name="defaultTargetSessionFactory" ref="oracleSessionFactory"/&
&property name="targetSessionFactorys"&
&entry value-ref="oracleSessionFactory" key="oracle"/&
&entry value-ref="mySQLSessionFactory" key="mysql"/&
&/property&
&!-- 自定义动态切换SessionFactory事务管理器,注入sessionFactory
&bean id="transactionManager" class="com.hoo.framework.spring.support.tx.DynamicTransactionManager"&
&property name="sessionFactory" ref="sessionFactory" /&
&!-- 配置事务的传播特性 --&
&tx:advice id="txAdvice" transaction-manager="transactionManager"&
&tx:attributes&
&tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="edit*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="remove*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="execute*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="*" read-only="true" /&
&/tx:attributes&
&/tx:advice&
&!-- 配置那些类、方法纳入到事务的管理 --&
&aop:config&
&aop:pointcut expression="execution(* com.hoo.**.service.impl.*.*(..))" id="transactionManagerMethod"/&
&aop:advisor advice-ref="txAdvice" pointcut-ref="transactionManagerMethod" /&
&/aop:config&
配置也和我们之前的配置差不多,就是事务管理器部分注入的SessionFactory是我们自己定义的。
5、简单测试
public void testAdd() {
// 主要就是这行代码 它才是完成SessionFactory的切换
CustomerContextHolder.setCustomerType(CustomerContextHolder.SESSION_FACTORY_MYSQL);
DeviceInfo entity = new DeviceInfo();
entity.setSbbh(System.currentTimeMillis() + "");
entity.setIpdz("my ip address2");
entity.setJd(1234);
service.add(entity);
} catch (Exception e) {
e.printStackTrace();
经过测试发现可以查询数据,利用hibernate查询分页也可以生成对应数据库的分页语句。同样在服务层的方法中添加完操作后,特意抛出一个异常,数据也能正常回滚操作,所以DynamicTransactionManager也是起到了该有的作用!
这里我的测试用例是手动切换CustomerContextHolder.setCustomerType的,但实际开发中我们还是得用Spring的Aop中的Interceptor进行切面,完成动态切换SessionFactory。上一篇文章Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法已经提到了(读者可以参考该篇博文中的第二节的3、7小节DataSourceMethodInterceptor MultipleDataSourceInterceptor),这里就不再赘述!
三、引发的问题
上述的实现如果在使用不当的情况下,在实际开发中很可能存在一些问题!
问题1是这样的,通常事务是在Service这层完成,这个应该是没有异议。倘若是这样的话,问题便出现了。而通常我们在MVC中的视图层中仅仅会调用Service中一个方法来完成所有当前业务的处理。如果这个Service中同时操作dbA、dbB两个数据库,事务提交的时候是用哪个数据库的事务呢?所以我们把不同数据库的操作放在一个方法,就会出现事务的问题的,除非两个数据库的事务能够同时回滚!
大致情景是:Service中的add4Oracle操作Oracle数据库,Service中的add4MySQL操作MySQL数据库,最后把Service中的add4Oracle、add4MySQL方法放到一个operation方法中,MVC视图层的业务控制调用Service中的operation。像这样的情况,如果add4Oracle或add4MySQL方法中的某一个方法出现异常,就需要把两个数据库事务都回滚。
解决办法就是在Service或Dao中的一个方法中同时操作两个数据库,手动完成事务控制。出现异常就全部回滚,没有异常就全部提交,只能这样牺牲下。
问题2是利用拦截器不能同时切换一个方法操作两个数据库的可能,例如一个service中的query方法即需要用query MySQL,也需要query Oracle。那么解决办法就是在query方法中调用当前service的query4Oracle和query4Oracle,那样绕过去还是能利用拦截器进行动态切换的。
要完成数据库方言的切换,我们就需要配置多个SessionFactory利用自己实现的DynamicSessionFactory和CustomerContextHolder完成SessionFactory的切换。利用DynamicTransactionManager完成当前Session的事务操作。通过对这些对象的操作和配置,最终可以完成SessionFactory的动态切换。实际使用中虽然有些问题出现,但是最终还是有解决方案,尽管有些不完美。所谓的完美的东西总有它不完美的地方,这样才算完美,比如断臂的维纳斯女神~!
红黑联盟&版权所有
Copyright&& 2017
All rights reserved.package com.zz.
import org.hibernate.HibernateE
import org.hibernate.S
import org.hibernate.cfg.C
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution.
Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
public class HibernateSessionFactory {
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
private static final ThreadLocal&Session& threadLocal = new ThreadLocal&Session&();
private static org.hibernate.SessionFactory sessionF
private static Configuration configuration = new Configuration();
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static String configFile = CONFIG_FILE_LOCATION;
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
private HibernateSessionFactory() {
* Returns the ThreadLocal Session instance.
Lazy initialize
* the &code&SessionFactory&/code& if needed.
@return Session
@throws HibernateException
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
session = (sessionFactory != null) ? sessionFactory.openSession()
threadLocal.set(session);
Rebuild hibernate session factory
public static void rebuildSessionFactory() {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
Close the single hibernate session instance.
@throws HibernateException
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
return session factory
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionF
return session factory
* session factory will be rebuilded in the next call
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configF
sessionFactory =
return hibernate configuration
public static Configuration getConfiguration() {
HibernateSessionFactory类是自定义的SessionFactory,名字可以根据自己的喜好来决定。这里用的是HibernateSessionFactory,其及解释。上述代码是由myeclipse 自动生成的;也可以根据自己的情况写出:
package com.zz.
import org.hibernate.SessionF
import org.hibernate.cfg.C
//在使用hibernate开发项目,请一定保证只有一个SessionFactory
//一个数据库对应一个SessionFactory 对象.
final public class MySessionFactory {
private static SessionFactory sessionFactory=
private MySessionFactory(){
sessionFactory =new Configuration().configure("com/zz/config/hsp.cfg.xml").buildSessionFactory();
System.out.println("sessionFactory 类型"+sessionFactory);
public static SessionFactory getSessionFactory(){
return sessionF
在Hibernate中,Session负责完成对象持久化操作。该文件负责创建Session对象,以及关闭Session对象。从该文件可以看出,Session对象的创建大致需要以下3个步骤:
① 初始化Hibernate配置管理类Configuration。
② 通过Configuration类实例创建Session的工厂类SessionFactory。
③ 通过SessionFactory得到Session实例。
³1. Configuration接口
Configuration负责管理Hibernate的配置信息。Hibernate运行时需要一些底层实现的基本信息。这些信息包括:数据库URL、数据库用户名、数据库用户密码、数据库JDBC驱动类、数据库dialect。用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现,如Hibernate数据库类型到特定数据库数据类型的映射等。
使用Hibernate必须首先提供这些基础信息以完成初始化工作,为后续操作做好准备。这些属性在Hibernate配置文件hibernate.cfg.xml中加以设定,当调用:
Configuration config=new Configuration().configure();
时,Hibernate会自动在目录下搜索hibernate.cfg.xml文件,并将其读取到内存中作为后续操作的基础配置。
2. SessionFactory接口
SessionFactory负责创建Session实例,可以通过Configuration实例构建SessionFactory。
Configuration config=new Configuration().configure();
SessionFactorysessionFactory=config.buildSessionFactory();
Configuration实例config会根据当前的数据库配置信息,构造SessionFacory实例并返回。SessionFactory一旦构造完毕,即被赋予特定的配置信息。也就是说,之后config的任何变更将不会影响到已经创建的SessionFactory实例sessionFactory。如果需要使用基于变更后的config实例的SessionFactory,需要从config重新构建一个SessionFactory实例。
SessionFactory保存了对应当前数据库配置的所有映射关系,同时也负责维护当前的二级数据缓存和Statement Pool。由此可见,SessionFactory的创建过程非常复杂、代价高昂。这也意味着,在系统设计中充分考虑到SessionFactory的重用策略。由于SessionFactory采用了线程安全的设计,可由多个线程并发调用。
³3. Session接口
Session是Hibernate持久化操作的基础,提供了众多持久化方法,如save、update、delete等。通过这些方法,透明地完成对象的增加、删除、修改、查找等操作。
同时,值得注意的是,HibernateSession的设计是非线程安全的,即一个Session实例同时只可由一个线程使用。同一个Session实例的多线程并发调用将导致难以预知的错误。
Session实例由SessionFactory构建:
Configuration config=new Configuration().configure();
SessionFactorysessionFactory=config.buldSessionFactory();
Session session=sessionFactory.openSession();
³4. Transaction接口
Transaction是Hibernate中进行事务操作的接口,Transaction接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA中的UserTransaction,甚至可以是CORBA事务。之所以这样设计是可以让开发者能够使用一个统一的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移值。事务对象通过Session创建。例如以下语句:
Transaction ts=session.beginTransaction();
³5. Query接口
在Hibernate 2.x中,find()方法用于执行HQL语句。Hibernate 3.x废除了find()方法,取而代之的是Query接口,它们都用于执行HQL语句。Query和HQL是分不开的。
Query query=session.createQuery(&fromtable where id=1&);
例如以下语句:
Query query=session.createQuery("fromtable whereid=?");
就要在后面设置其值:
Query.setString(0,"要设置的值");
上面的方法是通过&?&来设置参数,还可以用&:&后跟变量的方法来设置参数,如上例可以改为:
Query query=session.createQuery("fromtable whereid=:1");
Query.setString("kchValue","要设置的课程号值");
其使用方法是相同的,例如:
Query.setParameter(0,"要设置的值");
Query还有一个list()方法,用于取得一个List集合的示例,此示例中包括可能是一个Object集合,也可能是Object数组集合。例如:
Query query=session.createQuery("fromtable whereid=1");
List list=query.list();
阅读(...) 评论()}

我要回帖

更多关于 hibernate 实体类 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信