测试action,报错 Already value [org.springframework.orm.hibernate3.SessionHolder] for key

测试action,见http://blog.csdn.net/jazywoo123/article/details/8267208

但是写测试用例时,

package bijian.controller.action;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.UUID;



import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.mock.web.MockHttpSession;

import com.opensymphony.xwork2.Action;


import bijian.model.bean.Label;
import bijian.model.bean.Sentence;
import bijian.model.bean.User;

public class PageActionTests extends ActionTestBase{
	
    public void testDisplayHomepage() throws Exception{
//    	User user=new User();
//    	user.setUserID(100);
//    	user.setUsername("jazywoo");
//    	this.request.getSession().putValue("loginUser", user);
    	String result=this.executeAction("/pageAction!displayHomepage.action");
    	//Assert.assertEquals(Action.SUCCESS,result);
    	Map resultMap=(Map) findValueAfterExecute("resultMap");
    	List<User> hotUserList=(List<User>) resultMap.get("homepage_hotUserList");
    	List<Sentence> sentenceList=(List<Sentence>) resultMap.get("homepage_sentenceList");
    	List<Label> hotLabelList=(List<Label>) resultMap.get("homepage_hotLabelList");
    	System.out.println(hotUserList.get(0).getNickname());
//    	System.out.println(sentenceList.get(0).getContent());
//    	System.out.println(hotLabelList.get(0).getContent());
    }
    public void testDisplayUserHomepage() throws Exception{
    	User user=new User();
    	user.setUserID(100);
    	user.setUsername("jazywoo");
    	HttpSession session=new MockHttpSession();
//    	String sessionID=UUID.randomUUID().toString();
//    	session.setAttribute(ConstParameter.USER_SESSION, sessionID);
    	session.putValue("loginUser", user);
    	this.request.setSession(session);
    	
    	String result=this.executeAction("/pageAction!displayUserHomepage.action");
    	//Assert.assertEquals(Action.SUCCESS,result);
    	Map resultMap=(Map) findValueAfterExecute("resultMap");
    	String userHomePage_type=(String) resultMap.get("userHomePage_type");
    	Assert.assertEquals("suggest", userHomePage_type);
    }
}

会报错

java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate3.SessionHolder@6a4d1a] for key [org.hibernate.impl.SessionFactoryImpl@4bd173] bound to thread [main]
	at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:189)
	at bijian.controller.action.ActionTestBase.setUp(ActionTestBase.java:27)
	at junit.framework.TestCase.runBare(TestCase.java:132)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
	at ...............................

主要是

java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate3.SessionHolder@6a4d1a] for key [org.hibernate.impl.SessionFactoryImpl@4bd173] bound to thread

使用StrutsSpringTestCase 测试时, TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));的理解如下:

在调用一个需要事务的组件的时候,管理器首先判断当前调用(即当前线程)有没有一个事务,如果没有事务则启动一个事务,并把事务与当前线程绑定。Spring使用TransactionSynchronizationManager的bindResource方法将当前线程与一个事务绑定,采用的方式就是ThreadLocal,

@Override  
     protected void setUp() throws Exception {  
         super.setUp();  
         SessionFactory sessionFactory = lookupSessionFactory(this.request);  
         Session hibernateSession= getSession(sessionFactory);  
         TransactionSynchronizationManager.bindResource(sessionFactory,new SessionHolder(hibernateSession));  
     }  
     private Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {  
         Session session = SessionFactoryUtils.getSession(sessionFactory, true);  
         FlushMode flushMode = FlushMode.NEVER;  
         if (flushMode != null) {  
            session.setFlushMode(flushMode);  
         }  
          return session;  
     }  
     private SessionFactory lookupSessionFactory(HttpServletRequest request) {  
         //“sessionFactory”是你spring配置文件(通常是application.xml)中的SessionFactory。  
         //如:org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean  
         return (SessionFactory)this.applicationContext.getBean("sessionFactory");  
     }  

而测试时,有多个用例,相当于请求多次,hibernate的session再次关联到线程,因而会报错java.lang.IllegalStateException: Already value [org.springframework.orm.hibernate3.SessionHolder@6a4d1a] for key [org.hibernate.impl.SessionFactoryImpl@4bd173] bound to thread

我解决的方式是,在异常处使用try catch语句,如果是抛出的异常,则不再将session关联到线程

package bijian.controller.action;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.StrutsSpringTestCase;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import bijian.controller.action.UserAction;

public class ActionTestBase  extends StrutsSpringTestCase {
	
	 /*这个函数相当@Before注解的函数,是调用单元测试后的时候,
	    首先会执行的方法。可以在这里面做一些必要的准备工作*/
	 @Override
	 protected void setUp() throws Exception {
	     super.setUp();
	     SessionFactory sessionFactory = lookupSessionFactory(this.request);
	     Session hibernateSession= getSession(sessionFactory);
	     try{
	    	 TransactionSynchronizationManager.bindResource(sessionFactory,new SessionHolder(hibernateSession));
	     }catch(IllegalStateException e){
	         //e.printStackTrace();
	    	 //session已经关联存在,不再将session关联到线程
	     }
	     
	 }
	 @Override
	 public String getContextLocations() {
	   //返回你项目中spring配置文件所在的目录
	   return "/spring.xml";
	 }
	 private Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
	     Session session = SessionFactoryUtils.getSession(sessionFactory, true);
	     FlushMode flushMode = FlushMode.NEVER;
	     if (flushMode != null) {
	        session.setFlushMode(flushMode);
	     }
	      return session;
	 }
	 private SessionFactory lookupSessionFactory(HttpServletRequest request) {
	     //“sessionFactory”是你spring配置文件(通常是application.xml)中的SessionFactory。
	     //如:org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
	     return (SessionFactory)this.applicationContext.getBean("sessionFactory");
	 }
	 		
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值