關於hibernate的一些事

關於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>
相關文章
相關標籤/搜索