我的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中,无法从主程序继续活动事务?
答案 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