关于hibernate的一些事

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-02 10:09:17

关于hibernate的一些事 (此博文为http://my.oschina.net/u/555061/blog/506216后续

1.简单说一下SessionFactory、Session 源自: http://blog.csdn.net/javaloveiphone/article/details/8155340

1.1、Hibernate中SessionFactory对象的创建代价很高,它是线程安全的对象,被设计成可以为所有的应用程序线程所共享。通常,SessionFactory会在应用程序启动时创建,一旦创建了SessionFactory将不会轻易关闭,只有当应用关闭时,SessionFactory才会关闭
1.2、而Session的对象是轻量级的,它是线程不安全的。对于单个业务进程单个工作单元而言,Session只被使用一次。创建Session时,并不会立即打开与数据库之间的连接,Session只在需要进行数据库操作时,才会获取JDBC连接。因此,打开和关闭Session,并不会对性能造成很大的影响。甚至即使无法确定一个请求是否需要数据访问,也可以打开Session对象,因为如果不进行数据库访问,Session不会获取JDBC连接。
使用Spring管理hibernate的事务,在每个dao操作中使用SessionFactory.getCurrentSession()方法,该方法可以得到当前事务绑定的session。同时当前的Session和关联的Hibernate事务被绑定到当前线程上,虽然session不是线程安全的,但是通过这样的方式,每一个session都处于单线程中,避免session线程安全问题

1.3、不通过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();

前面1、2点都是没什么问题,但是第3点事务的问题,我跟该博主意见不一致,首先Spring可以管理由Hibernate的SessionFactory产生的事务,所以通过Spring管理Hibernate的事务是可行的。其次,在开启事务配置的同时,框架已经在自动帮你管理事务,也就是刚刚连续两个操作,一个save一个sqlquery,由于sqlquery失败导致save同时失败回滚(或者说就没有commit的后续操作),而如果再使用session.beginTransaction()则会导致org.hibernate.TransactionException: nested transactions not supported错误,分析字面上的意思和根据本人查询结果综合来看,就是因为多次开启事务导致错误,反过来说事务不需要在session.beginTransaction()的情况下才开启,框架自动已经就在配置好以后就开启了。


2.关于org.hibernate.MappingException: Unknown entity:错误

本人在发生的时候是由于没有写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的有另一种配置,其实也只是换汤不换药,这种方式未测试成功但应该是能用的,因此用*****代替需要配置的地方,先记录下

<property name="mappingDirectoryLocations">  
    <list>  
        <value>classpath:****</value>  
    </list>  
</property>


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!