关于hibernate的一些事 (此博文为http://my.oschina.net/u/555061/blog/506216后续)java
1.简单说一下SessionFactory、Session 源自: http://blog.csdn.net/javaloveiphone/article/details/8155340spring
1.一、Hibernate中SessionFactory对象的建立代价很高,它是线程安全的对象,被设计成能够为全部的应用程序线程所共享。一般,SessionFactory会在应用程序启动时建立,一旦建立了SessionFactory将不会轻易关闭,只有当应用关闭时,SessionFactory才会关闭。
1.二、而Session的对象是轻量级的,它是线程不安全的。对于单个业务进程单个工做单元而言,Session只被使用一次。建立Session时,并不会当即打开与数据库之间的链接,Session只在须要进行数据库操做时,才会获取JDBC链接。所以,打开和关闭Session,并不会对性能形成很大的影响。甚至即便没法肯定一个请求是否须要数据访问,也能够打开Session对象,由于若是不进行数据库访问,Session不会获取JDBC链接。
使用Spring管理hibernate的事务,在每一个dao操做中使用SessionFactory.getCurrentSession()方法,该方法能够获得当前事务绑定的session。同时当前的Session和关联的Hibernate事务被绑定到当前线程上,虽然session不是线程安全的,可是经过这样的方式,每个session都处于单线程中,避免session线程安全问题sql
1.三、不经过Spring管理事务,开启事务的主动性:数据库
在sessionFactory.openSession()中,Hibernate会初始化数据库链接,与此同时,将其 AutoCommit设为关闭状态,这就是说,从SessionFactory得到session,其自动提交属性就已经被关闭了,事务须要主动、显示的调用才能生效,下面的代码不会对事务性数据库产生任何效果。
session=sessionFactory.openSession();
session.save(user);
session.close();
若是要使得代码真正做用到数据库,必须显示的调用Transaction指令
session=sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close();安全
前面一、2点都是没什么问题,可是第3点事务的问题,我跟该博主意见不一致,首先Spring能够管理由Hibernate的SessionFactory产生的事务,因此经过Spring管理Hibernate的事务是可行的。其次,在开启事务配置的同时,框架已经在自动帮你管理事务,也就是刚刚连续两个操做,一个save一个sqlquery,因为sqlquery失败致使save同时失败回滚(或者说就没有commit的后续操做),而若是再使用session.beginTransaction()则会致使org.hibernate.TransactionException: nested transactions not supported错误,分析字面上的意思和根据本人查询结果综合来看,就是由于屡次开启事务致使错误,反过来讲事务不须要在session.beginTransaction()的状况下才开启,框架自动已经就在配置好之后就开启了。session
2.关于org.hibernate.MappingException: Unknown entity:错误app
本人在发生的时候是因为没有写packagesToScan,觉得能够在Spring自动包扫描的时候注册hibernateEmployee这个包下面的类为bean,没想到不行,须要在这里写框架
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>com.zhxjz.model.hibernateEmployee</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="dialect">${hibernate.dialect}</prop> <prop key="show_sql">${hibernate.show_sql}</prop> <!-- <prop key="hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> --> </props> </property> </bean>
有博客提到代替packagesToScan的有另外一种配置,其实也只是换汤不换药,这种方式未测试成功但应该是能用的,所以用*****代替须要配置的地方,先记录下iphone
<property name="mappingDirectoryLocations"> <list> <value>classpath:****</value> </list> </property>