Hibernate “调试休眠”;会议结束了"E;”滥用单边带?

Hibernate “调试休眠”;会议结束了"E;”滥用单边带?,hibernate,stateless-session-bean,Hibernate,Stateless Session Bean,(首先,这不是我的代码。其次,为了保护罪犯,我更改了类名以隐藏特定于我雇主的任何内容,因此,如果事情不一致,这就是原因!) 有人能帮我澄清一个疑问吗?我被要求调查一个完整连接池的问题,这段代码似乎有味道 我们有很多org.hibernate.SessionException:会话已关闭在我们的日志中,围绕下面的代码,它使用的连接池表现不好 这些呼叫通过web服务传入: 1 @Stateless 2 @WebService(name="MyWebService", targetNamespac

(首先,这不是我的代码。其次,为了保护罪犯,我更改了类名以隐藏特定于我雇主的任何内容,因此,如果事情不一致,这就是原因!)

有人能帮我澄清一个疑问吗?我被要求调查一个完整连接池的问题,这段代码似乎有味道

我们有很多
org.hibernate.SessionException:会话已关闭在我们的日志中,围绕下面的代码,它使用的连接池表现不好

这些呼叫通过web服务传入:

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 }
MyHome
如下所示:

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 }
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
字段中,因此第一次调用可以很容易地将其
会话
替换为另一个
会话
,导致各种问题,包括
org.hibernate.SessionException:会话已关闭
在MyHome的第9行和第21行(例如,两个线程调用
findDataObject
,第一个线程在第二个线程运行第8行之后和第9行之前运行第14行)

我说得对吗?

是的,你说得对

另外,请注意,即使myHome不是静态的,myHome返回的所有对象都将与会话断开连接。您将无法从MyHome之外初始化惰性属性

会话变量也应该是MyHome方法中的局部变量,而不是实例变量

但主要的问题是,无状态会话bean应该用于以声明的方式划分事务。在EJB环境中,您不必打开、提交和回滚事务,也不必关闭会话。一切都应该由通过sessionFactory.getCurrentSession()实现的JTA事务同步来完成