EJB中使用Hibernate的方法以及常见问题

来源:岁月联盟 编辑:zhuzhu 时间:2007-09-06

EJB中使用Hibernate的方法应该大家都会,不过许多人可能没注意下面几个问题,首先我们来看下面这段代码。

public class HibernateTestBean implements SessionBean ...{     SessionContext sessionContext;     SessionFactory sf;     public void setSessionContext(SessionContext sessionContext) ...{         this.sessionContext = sessionContext;         try ...{             InitialContext ctx = new InitialContext();             sf=(SessionFactory) ctx.lookup("java:/hibernate/SessionFactory");         } catch (NamingException ex) ...{             ex.printStackTrace();         }     }     public void tran()...{         tran1();         tran2();     }     public void tran1() ...{         Session session=sf.getCurrentSession();         Message msg=new Message();         msg.setCreateTime(new Date());         msg.setDetail("trans1");         session.save(msg);         System.out.println("Session:"+session.hashCode());         session.flush();         session.close();     }     public void tran2() ...{       Session session=sf.getCurrentSession();       Message msg=new Message();       msg.setCreateTime(new Date());       msg.setDetail("trans2");       session.save(msg);        System.out.println("Session:"+session.hashCode());  //  throw new RuntimeException("wrong");   } …… }

注:EJB采用CMT,各方法的事务属性是required

客户端调用tran以上代码可以正确运行吗?

如果把tran1中的sf.getCurrentSession();改为sf.openSession()可以正确运行吗?

辨析:

1 上述代码是不能正确运行的,运行tran2时会抛出异常,告诉你session is closed.

其实这是应为getCurrentSession()会使用环境已有的Session,同时注意getCurrentSession()要在事务的环境中使用。

这是也许你一定会问,那么什么时候关闭Session呢?答案是事务完成的时候(提交或是回滚)。

2 如果上述代码tran1中的sf.getCurrentSession();改为sf.openSession()代码将可以正确运行。这是因为openSession()每次都会返回一个新的Session。而在tran2种的sf.getCurrentSession()并不会使用tran1中的session,而是会使用当前事务环境中的默认的session.

也许你会问如果tran2种的调用抛出RuntimeException,tran1所作的操作还可以回滚吗?

答案是仍然可以回滚的.