我在一个SessionBean中使用动态注入获得了一个EntityManger。 @PersistenceContext
private EntityManager entityManager;
persistence.xml配置如下: <persistence-unit name="LMS2">
<jta-data-source>java:/MySqlDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="none" />
</properties>
</persistence-unit>然后再一个Action中,获得SessionBean中的EntityManager对象后调用getTransaction方法获取一个事务,如:
this.sessionBean.getEntityManager().getTransaction();在本地的JUnit测试驱动中运行没有问题,但是一旦发布到JBoss服务器上运行就出错了。通过调试发现,问题正正出现在上述语句中,也就是getTransaction()方法,运行到该方法时抛出了IllegalStateException异常,异常信息如下:请问各位,这个是什么原因导致的???应该如何解决这个问题

解决方案 »

  1.   

    之前好像遇到过。。手动创造索引。。
    List books = em.createQuery("select book from Book as book").getResultList(); 
    for (Book book : books) { 
        fullTextEntityManager.index(book); 
    } em.getTransaction().commit(); 
    em.close(); 
      

  2.   

    因为你声明的是 JTA 事务,因此不能再使用 EntityTransaction 了。需要使用 JTA 进行事务控制。1:在 Session Bean 的类上加上 Bean 管理的事务声明:@TransactionManagement(TrahsactionManagerType.BEAN)2:在 session bean 中加上 UserTransaction 一个成员变量,使用 @Resource 注入
    @Resource
    private UserTransaction ut;或者先注入 EjbContext,再使用 EjbContext 中获得 UserTransaction 对象
    @Resource
    private EjbContext ejbContext;3:使用 UserTransaction 的 begin(), commit(), rollback() 进行操作需要注意的是:1:@TransactionManagement(TrahsactionManagerType.BEAN) 一加,这个 bean 所有的事务都必须手工控制,这时这个 bean 称为 BMT,否则就是容器管理的事务 CMT
    2:stateless session bean 自己管理的事务必须在一个方法内开始和结束,stateful session bean 可以在一个方法中开始,在另外一个方法中结束。
      

  3.   

    感谢楼上两位的回答~~~
    但是我还是有两点疑问:
    1. 为何我在 JUnit4 的单元测试中执行到这段代码的时候不会报错,而发布到服务器时才出错呢?
    2. 假如我在一个非 SessionBean 的类中调用了 flush() 函数(代码如下),系统就会报错提示需要一个事务,但是却不能获取事务,这个是为何???this.sessionBean.getEntityManager().getTransaction().begin(); // 如果不添加这段代码,下面flush就会出错,如果添加这段代码这段代码就出错。
    this.sessionBean.getEntityManager().flush();