關於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>