hibernate单会话活动事务

时间:2015-06-30 13:05:41

标签: hibernate session transactions

我的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 个答案:

答案 0 :(得分:1)

每当你想在Hibernate(3.0.1+)中处理上下文会话时,你应该使用getCurrentSession()。您不需要(也不应该)首先致电openSession()。来自manual (v4.3, §3.9.3)

  

使用“jta”会话上下文,如果没有与当前JTA事务关联的Hibernate Session,则会在您第一次调用sessionFactory.getCurrentSession()时启动并与该JTA事务关联。 / p>

相比之下,openSession始终会打开一个新会话,然后您应该在它超出范围之前关闭(例如使用try-with-resources)。由openSession打开的会话不是休眠上下文会话。

您可以(通常)通过比较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