论坛首页 Java企业应用论坛

spring的事务不起作用?无法和当前sessin绑定?

浏览 25060 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-05  
我使用 spring的声明式的事务,但是运行的时候报错:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and conf
iguration does not allow creation of non-transactional one here
        at org.springframework.orm.hibernate3.AbstractSessionFactoryBean$Transac
tionAwareInvocationHandler.invoke(AbstractSessionFactoryBean.java:296)
        at $Proxy1.getCurrentSession(Unknown Source)
        at com.liferay.portlet.lyo.service.persistence.TestUtil.testquery(TestUt
il.java:54)

我在配置文件中明明配置了事务的!:
<bean id="com.liferay.portlet.lyo.service.persistence.TestUtil" class="com.liferay.portlet.lyo.service.persistence.TestUtil" lazy-init="true">
		
		<property name="sessionFactory">
			<ref bean="liferaySessionFactory" />
		</property>
	</bean>
<bean id="myProductService"
      class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" lazy-init="true">
    <property name="transactionManager" ref="liferayTransactionManager"/>
    <property name="target">
      <bean class="com.liferay.portlet.lyo.service.persistence.TestUtil">
      </bean>
    </property>
    <property name="transactionAttributes">
      <props>
        <prop key="test*">PROPAGATION_REQUIRED,readOnly</prop>
      </props>
    </property>
  </bean>

我在代码中注入的sessionFactory可以得到,说明IOC式起作用的,但是代码不能使用getCurrentSession方法,如果使用就报上面的错误!我的代码:
public  static List testquery(){
		List list=new ArrayList();
		TestUtil tu=new TestUtil();
		Session hsession=tu.getSessionFactory().getCurrentSession();
		list=hsession.createQuery("from UserImpl as u").list();
		hsession.close();
		return list;
		
	}

把其中的 getCurrentSession改成 openSession 就可以使用! 很明显是因为那个 allowCreate的问题,当没有事务启动的时候,getCurrentSession是无法创建Session的! 说明配置事务没有成功!但是我的配置已经和例子一摸一样了啊~ 哪位朋友能帮忙找出错误? 谢谢!
   发表时间:2007-06-05  
1先说为什么openSession可以,opensession是从sessionfactory得到一个新的session,所以可以使用,而getCurrentSession是从当前线程中得到事务开始时创建transaction的那个session,而你的事务没有能正确的启动,所以并没有一个session绑定到当前线程,所以你也得不到。
2你的testquery在哪个类里,你的new TestUtil的对象有没有交给spring管理
0 请登录后投票
   发表时间:2007-06-05  
ahuaxuan 写道
1先说为什么openSession可以,opensession是从sessionfactory得到一个新的session,所以可以使用,而getCurrentSession是从当前线程中得到事务开始时创建transaction的那个session,而你的事务没有能正确的启动,所以并没有一个session绑定到当前线程,所以你也得不到。
2你的testquery在哪个类里,你的new TestUtil的对象有没有交给spring管理


多谢,第一个原因我知道是因为这个,你说得第二个,"TestUtil tu=new TestUtil();  
" 应该怎样修改呢?
0 请登录后投票
   发表时间:2007-06-05  
我改成这样,但是仍然报那个错误:
private static SessionFactoryImplementor sessionFactory;
	
	
	public  SessionFactoryImplementor getSessionFactory() {
		return sessionFactory;
	}

	public  void setSessionFactory(SessionFactoryImplementor factory) {
		sessionFactory = factory;
	}
public   List testquery(){
		List list=new ArrayList();
		
		Session hsession=this.getSessionFactory().getCurrentSession();
		list=hsession.createQuery("from UserImpl as u").list();

		hsession.close();
		return list;
		
	}

现在里面应该全是spring管理了吧?
0 请登录后投票
   发表时间:2007-06-05  
1你的sessionfactory是否是hibernate的sessionfactory呀,俺觉得这个getSessionFactory().getCurrentSession();   是hibernate包中的方法,我的建议是不要把sessionfactory注入到你的testutil类中,因为我想我们不应该破坏spring对hibernate的封装(我并没有在org.springframework.orm.hibernate3.LocalSessionFactoryBean这个类里发现getCurrentSession()方法,所以我认为你直接配置了hibernate的sessionfactory,而不是localsessionfactorybean)

2针对上一点,你可以把hibernatetemplate注入到你的testutil类中去会比较好,我们让spring来管理sessionfactory,你可以通过hibernatetemplate来得到session等等
0 请登录后投票
   发表时间:2007-06-05  
ahuaxuan 写道
1你的sessionfactory是否是hibernate的sessionfactory呀,俺觉得这个getSessionFactory().getCurrentSession();   是hibernate包中的方法,我的建议是不要把sessionfactory注入到你的testutil类中,因为我想我们不应该破坏spring对hibernate的封装(我并没有在org.springframework.orm.hibernate3.LocalSessionFactoryBean这个类里发现getCurrentSession()方法,所以我认为你直接配置了hibernate的sessionfactory,而不是localsessionfactorybean)

2针对上一点,你可以把hibernatetemplate注入到你的testutil类中去会比较好,我们让spring来管理sessionfactory,你可以通过hibernatetemplate来得到session等等

好像得确不是,sessionFactory是:
<bean id="liferaySessionFactory" class="com.liferay.portal.spring.hibernate.HibernateConfiguration" lazy-init="true">
		<property name="dataSource">
			<ref bean="liferayDataSource" />
		</property>
	</bean>

他继承的也是 LocalSessionFactoryBean
HibernateConfiguration的代码是:
public class HibernateConfiguration extends LocalSessionFactoryBean {

	protected Configuration newConfiguration() {
		Configuration cfg = new Configuration();

		try {
			ClassLoader classLoader = getClass().getClassLoader();

			String[] configs = StringUtil.split(
				PropsUtil.get(PropsUtil.HIBERNATE_CONFIGS));

			for (int i = 0; i < configs.length; i++) {
				try {
					InputStream is =
						classLoader.getResourceAsStream(configs[i]);

					if (is != null) {
						cfg = cfg.addInputStream(is);

						is.close();
					}
				}
				catch (Exception e) {
					e.printStackTrace();
				}
			}

			cfg.setProperties(PropsUtil.getProperties());
		}
		catch (Exception e) {
			_log.error(StackTraceUtil.getStackTrace(e));
		}

		return cfg;
	}

	private static Log _log = LogFactory.getLog(HibernateConfiguration.class);

}

但是里面没有做任何限制吧?
0 请登录后投票
   发表时间:2007-06-05  
lyo 写道

                  List list=new ArrayList();
TestUtil tu=new TestUtil();
Session hsession=tu.getSessionFactory().getCurrentSession();
list=hsession.createQuery("from UserImpl as u").list();
hsession.close();
return list;



关键还是你在这里TestUtil tu=new TestUtil()得到的TestUtil是没有被spring的事务管理的, 你必须从ApplicationContext中去获得。
但我不明白的是, 从这段代码看不出来TestUtil为什么需要被事务管理, 你好像只是为了从里面拿sessionfactory。
再有就是你的配置中:
    <property name="target"> 
      <bean class="com.liferay.portlet.lyo.service.persistence.TestUtil"> 
      </bean> 
    </property> 

为什么不直接用<ref bean="..."/>
0 请登录后投票
   发表时间:2007-06-05  
原来你是在liferay里啊,但是我有一点不明白,你是如何做到把HibernateConfiguration的实例赋给SessionFactoryImplementor 的引用的呢,这两个类型完全不一样啊,而且hibenate包中的ssionFactoryImplementor类根本没有getCurrentSession()方法,于是我就迷惑了,难道这是liferay对hibernate的封装
0 请登录后投票
   发表时间:2007-06-05  
spiritfrog 写道
lyo 写道

                  List list=new ArrayList();
TestUtil tu=new TestUtil();
Session hsession=tu.getSessionFactory().getCurrentSession();
list=hsession.createQuery("from UserImpl as u").list();
hsession.close();
return list;



关键还是你在这里TestUtil tu=new TestUtil()得到的TestUtil是没有被spring的事务管理的, 你必须从ApplicationContext中去获得。
但我不明白的是, 从这段代码看不出来TestUtil为什么需要被事务管理, 你好像只是为了从里面拿sessionfactory。

青蛙看一下4楼
0 请登录后投票
   发表时间:2007-06-05  
把hibernate的源代码看了一下,发现SessionFactoryImpl有getCurrentSession()方法,而sessionFactoryImplementor里确实没有这个方法。

而且我想应该是这样的,
你通过sessionfactoryimpl的getCurrentSession方法其实是这样的,这个session是通过直接放到线程之中,即key是sessionfactory,value就是这个session。而在spring对hibernate的封装中,session是放到sessionholder这个类中,然后sessionholder又通过sessionfactory放到线程中(即sessionfactory是key,而sessionholder是value),所以在事务开始的时候,线程中其实已经有sessionholder了,这个是spring放进去的,而你在取的时候去取了直接放到线程中的session,显然之前你并没有放进去,所以会报session没有和线程绑定的异常,不知道是否是这样
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics