阿寶 Keep Walking......


          JUST DO IT, DO YOUR BEST ! -- 勿在浮沙筑高臺

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            49 Posts :: 6 Stories :: 26 Comments :: 0 Trackbacks

          如果在hibernate.cfg.xml中配置了
          ??<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>?
          ??<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
          ??<property
          name="hibernate.current_session_context_class">jta</property>
          這個配置的意思是當前對于這個SessionFactory(org.hibernate.transaction.CMTTransactionFactory的實例)來說,方法getCurrentSessiong()這個操作都應該在Container Manager Transaction中進行的,此時這個方法會將Session和Transaction進行綁定,對于應用來說則只需調用getCurrentSession就可以了,無需關心Session的Commit和Close.但是如果不是在一個Container Manager Transaction的Bean中調用SessionFactory.getCurrentSession(),則會拋出如下"org.hibernate.HibernateException: Unable to locate current JTA transaction"
          ,我想是因為容器沒有為當前的Bean開始事務,所以這個方法無法綁定Session到當前的JTA transaction中去.

          所以在配置前要想清楚是不是所有的操作都是在CMT中進行的,如果不是的話,不能夠進行這樣的操作.在一個應用中,往往有多個senarior,有的是通過CMT的session bean來調用,而有的則是通過Service直接調用DAO,要解決這個問題的話,可以配置多個SessiongFactory,將其Bind到容器的JNDI樹中去.在調用的時候根據當前的Senaior來取不同的SessionFactory.

          例如可以為所有通過的CMT管理的Bean作上述配置,對于BMT管理的配置如下:
          ??<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>?
          ??<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
          ??<property
          name="hibernate.current_session_context_class">jta</property>
          使用的代碼如下:
          //BMTidiomwithgetCurrentSession()
          try{
          ?UserTransactiontx=(UserTransaction)newInitialContext()
          ?.lookup("java:comp/UserTransaction");
          ?tx.begin();
          ?//DosomeworkonSessionboundtotransaction
          ?factory.getCurrentSession().load(...);
          ?factory.getCurrentSession().persist(...);
          ?tx.commit();
          }
          catch(RuntimeExceptione){
          ?tx.rollback();
          ?throwe;//ordisplayerrormessage
          }

          其實這里與CMT不同的就是要手動開始一個Transaction,SessionFactory檢查這個Transaction是否是Begin,然后綁定一個Session到這個Transaction上去.

          如果是在非托管的環境的應用的話,用JDBCTransactionFactory就可以了,另外對于hibernate.current_session_context_class可以設置為Thread,通過Session.getCurrentSesion()這個方法,讓每個Thread公用一個session,同樣你也無須關心Sesion的打開和關閉.
          //Non-managedenvironmentidiomwithgetCurrentSession()
          try{
          ?factory.getCurrentSession().beginTransaction();
          ?//dosomework
          ?...
          ?factory.getCurrentSession().getTransaction().commit();
          }
          catch(RuntimeExceptione){
          ?factory.getCurrentSession().getTransaction().rollback();
          ?throwe;//ordisplayerrormessage
          }
          注意如果采取這種方式獲得Session,即使對查詢語句也需要開始事務,否則會拋異常.
          org.hibernate.HibernateException: createSQLQuery is not valid without active transaction

          如果對于CMT,BMT和非托管環境都要用到的,則不再適合用SessionFactory.getCurrentSession(),而需要用OpenSession,并自己負責事務的提交以及Sesion的Close.

          posted on 2006-05-28 01:34 阿寶 閱讀(7004) 評論(1)  編輯  收藏

          Feedback

          # re: Hibernat 的SessionFactory的getCurrentSesion()方法詳解 2006-11-17 03:01 吳克
          JTA和CMT有什么區別嗎?我感覺沒什么區別嗎?一個是使用,一個是聲名,jdbc倒是和他們的區別很大!!  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 峨眉山市| 吉安县| 巍山| 威宁| 龙州县| 东莞市| 霸州市| 双流县| 黑龙江省| 黄浦区| 郸城县| 桂平市| 贺兰县| 交口县| 建平县| 康保县| 陈巴尔虎旗| 建水县| 巴青县| 册亨县| 应城市| 宁波市| 高平市| 师宗县| 县级市| 淮阳县| 庄河市| 达拉特旗| 疏勒县| 马关县| 嘉荫县| 湟中县| 云龙县| 萝北县| 张掖市| 芜湖市| 邵阳市| 庆城县| 乌拉特前旗| 若尔盖县| 陵川县|