调试Hibernate“会话已关闭!” - 滥用SSB?

(首先,这不是我的代码。其次,为了保护有罪,我改变了班级名称以隐藏我的雇主特有的东西,所以如果事情彼此不相符,那就是为什么!)。 有人可以帮我解决疑问吗?我被要求调查完整连接池的问题,这个代码似乎闻到了。 我们的日志中有很多
org.hibernate.SessionException: Session is closed!
,围绕以下代码,它使用表现不佳的连接池。 电话通过网络服务进入:
1  @Stateless
2  @WebService(name="MyWebService", targetNamespace="http://www.mycompany.com/2010/01/WebService/myWebService")
3  @WebContext(contextRoot="/myContextRoot", secureWSDLAccess=false)
4  public class MyWebService implements IMyWebService {

6    @WebMethod
7    @NotNull
8    public ArrayList<SearchResult> performSearch(ArrayList<String> criteria) {
9      GetAllResponses caller = new GetAllResponses();
10     return caller.doSearch(criteria);
11   }

13 }
GetAllResponses
课程如下:
1  public class GetAllResponses {
2    private static MyHome myHome = new MyHome();

4    public SearchResult doSearch(ArrayList<String> criteria) {
5      return doSearchInternal(criteria.elementAt(0), criteria.elementAt(1));
6    }

8    private SearchResult doSearchInternal(String a, String b) {
9      DataObject info = myHome.findDataObject(a, b);
10     return info.getAsSearchResult();
11   }
12 }
并且
MyHome
如下:
1  @Stateless
2  @Local({MyHomeInterface.class})
3  public class MyHome {
4    private Session session;

6    public DataObject findDataObject(String a, String b) {
7        try {
8            this.session = MyHibernateUtil.getSessionFactory().getCurrentSession();
9            Transaction tx = this.session.beginTransaction();
10           //do stuff with session and return a DataObject
11       } catch (Exception ex) {
12           ex.printStackTrace();
13       } finally {
14           this.session.close();
15       }
16   }

18   public DataObject doAnotherFind(String a, String b) {
19       try {
20           this.session = MyHibernateUtil.getSessionFactory().getCurrentSession();
21           Transaction tx = this.session.beginTransaction();
22           //do stuff with session and return a DataObject
23       } catch (Exception ex) {
24           ex.printStackTrace();
25       } finally {
26           this.session.close();
27       }
28  }

30 }
注意如何在
GetAllResponses
的第2行将
MyHome
类实例化为静态字段,并且在
MyHome
的第8行和第20行上分配字段
session
。 根据我对事物的理解,SSB
MyHome
不是由J2EE服务器(JBoss 4.2.2 GA)管理的,因为它已被实例化为
GetAllResponses
类的静态字段而不是在JNDI上查找。因此,两个线程可以同时访问同一个
MyHome
的实例,并且由于会话存储在字段
session
中,第一次调用很容易将其
Session
替换为另一个
Session
,导致各种问题,包括线路上的
org.hibernate.SessionException: Session is closed!
MyHome
的9和21(作为一个例子,两个线程调用
findDataObject
,第一个线程在第二个线程运行第8行之后且在它运行第9行之前运行第14行)。 我对么?     
已邀请:
是的,你是对的。 另外,请注意,即使myHome不是静态的,MyHome返回的所有对象也将与会话断开连接。您将无法从MyHome外部初始化惰性属性。 会话变量也应该是MyHome方法中的局部变量,而不是实例变量。 但主要问题是无状态会话bean应该用于以声明方式划分事务。在EJB环境中,您不必打开,提交和回滚事务,也不必关闭会话。一切都应该通过sessionFactory.getCurrentSession()实现的JTA事务同步来完成。     

要回复问题请先登录注册