2015-06-30 85 views
1

我的Hibernate的配置:休眠單個會話活動事務

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
<session-factory> 
     <property  name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
    <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property> 
    <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> 
    <property name="hibernate.default_schema">gg</property> 
    <property name="hibernate.current_session_context_class">thread</property> 
<property name="show_sql">false</property> 
<property name="format_sql">true</property> 
<property name="use_sql_comments">true</property> 

    <mapping class="com.greengrass.house.Obj"></mapping> 
    <mapping class="com.greengrass.house.ObjxProp"></mapping> 
    <mapping class="com.greengrass.house.Property"></mapping> 
    <mapping class="com.greengrass.house.EvQue"></mapping> 
    <mapping class="com.greengrass.house.EvxObj"></mapping> 
</session-factory> 
</hibernate-configuration> 

我的主要程序的部分:

我持續存在的對象
Session sess = HibernateUtil.getSessionFactory().openSession(); 
List<Obj> lobj = sess.createQuery(
    "from Obj").list(); 
sess.beginTransaction(); 
Obj o2=lobj.get(1); 
o2.crEvent("test", 3600, 1); //calling method 
sess.getTransaction().commit(); 

一種方法:

@Transient 
public void crEvent(String speech, int timeout, int maxCnt) { 
    Session s = HibernateUtil.getSessionFactory().getCurrentSession(); 
    if (!s.getTransaction().isActive()) { 
     System.out.println("No transaction!!!"); 
    } else { 
     System.out.println("Exist transaction!!!"); 
    } 
    Query query = s.createSQLQuery(
      "CALL p_event.cr_event(:p_speech, :p_tm, :p_max_cnt)") 
      .setParameter("p_speech", speech) 
      .setParameter("p_tm", timeout) 
      .setParameter("p_max_cnt", maxCnt); 
    int exRows = query.executeUpdate();  
} 

,所以我得到這個結果:

No transaction!!! <--Message from the my method 

Exception in thread "main" org.hibernate.HibernateException: createSQLQuery is not valid without active transaction 
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:348) 
    at com.sun.proxy.$Proxy16.createSQLQuery(Unknown Source) 
    at com.greengrass.house.Obj.crEvent(Obj.java:273) 
    at com.greengrass.evhandler.GreenEvHandler.main(GreenEvHandler.java:36) 

所以我不明白爲什麼是 HibernateUtil.getSessionFactory()。getCurrentSession();方法crEvent中的 ,不能從主程序繼續活動事務?

回答

1

無論何時您想在Hibernate(3.0.1+)中處理上下文會話,都應該使用getCurrentSession()。您不需要(也不應該)先撥打openSession()。從manual (v4.3, §3.9.3)

使用「JTA」會話背景下,如果沒有與當前JTA事務的Hibernate Session,一個將被啓動,並與JTA事務中的第一次調用sessionFactory.getCurrentSession()相關。

相反openSession總是打開一個新的會話,你應該然後關閉(例如用try-with-resources),它超出範圍了。由openSession打開的會話不是hibernate上下文會話。

可以(通常)查看兩個會話實例是相同的,通過比較hashCodes

Session s1 = HibernateUtil.getSessionFactory().getCurrentSession(); 
Session s2 = HibernateUtil.getSessionFactory().openSession(); 
Session s3 = HibernateUtil.getSessionFactory().getCurrentSession(); 
System.out.println("getCurrent is " + s1.hashCode()); 
System.out.println("openSession is " + s2.hashCode()); 
System.out.println("getCurrent is " + s3.hashCode()); 
s2.close(); 

輸出:

getCurrent is 392918519 
openSession is 1499840045 
getCurrent is 392918519 
+0

非常感謝你,所以我需要重新閱讀文檔, thanx在勸告! – Lev