有状态会话Bean的钝化问题

时间:2012-04-18 23:41:39

标签: java-ee-6 jboss6.x jboss-weld

我正在使用JBoss 6.1 Final,并在我的Web应用程序运行一段时间后收到以下错误消息(请注意应用程序不会崩溃),然后是非常长的堆栈跟踪。我注意到这个问题只发生在有状态会话bean中,其中有其他有状态会话bean注入其中。

  

16:10:59,769 ERROR [org.jboss.ejb3.cache.simple.SimpleStatefulCache.UutSerialNumberServiceBean]问题钝化线程:javax.ejb.EJBException:无法钝化;未能保存状态

这是违规的有状态会话bean ...

package com.ray.TEI.ejb;

import java.io.Serializable;

import javax.ejb.Stateful;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import com.ray.TEI.model.TestProcedure;
import com.ray.TEI.model.Uut;
import com.ray.TEI.model.UutSerialNumber;

@Stateful
public class UutSerialNumberServiceBean implements Serializable {
  private static final long serialVersionUID = 1L;
  @PersistenceContext(unitName="jasoni", type=PersistenceContextType.EXTENDED)
  protected EntityManager em;
  @Inject private ExecProcedureServiceBean execProcedureServiceBean;

  public boolean isDuplicateSerialNumber(Uut uut, String serialNumber) {
    return ((Number)em.createNamedQuery("UutSerialNumber.getCountByUutIdAndSerialNumber")
             .setParameter("uut", uut)
             .setParameter("serialNumber", serialNumber)
             .getSingleResult()).intValue() > 0;
  }

  public UutSerialNumber findUutSerialNumberByUutSerialNumberId(Integer uutSerialNumberId) {
    return em.find(UutSerialNumber.class, uutSerialNumberId);
  }

  public UutSerialNumber editSerialNumber(Integer uutSerialNumberId, String serialNumber) {
    UutSerialNumber uutSerialNumber = findUutSerialNumberByUutSerialNumberId(uutSerialNumberId);
    uutSerialNumber.setSerialNumber(serialNumber);
    return uutSerialNumber;
  }

  public UutSerialNumber createSerialNumber(Uut uut, String serialNumber) {
    UutSerialNumber uutSerialNumber = new UutSerialNumber();
    uutSerialNumber.setSerialNumber(serialNumber);
    uutSerialNumber.setUut(uut);
    uut.getSerialNumbers().add(uutSerialNumber);
    em.persist(uutSerialNumber);
    for (TestProcedure testProcedure : uut.getTestProcedures()) {
      execProcedureServiceBean.createExecProcedure(uutSerialNumber, testProcedure);
    }
    return uutSerialNumber;
  }
}

这是注入的有状态会话bean ...

package com.ray.TEI.ejb;

import java.io.Serializable;

import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import com.ray.TEI.model.ExecProcedure;
import com.ray.TEI.model.TestProcedure;
import com.ray.TEI.model.UutSerialNumber;


@Stateful
public class ExecProcedureServiceBean implements Serializable {
  private static final long serialVersionUID = 1L;
  @PersistenceContext(unitName="jasoni", type=PersistenceContextType.EXTENDED)
  protected EntityManager em;

  public ExecProcedure createExecProcedure(UutSerialNumber uutSerialNumber, TestProcedure testProcedure) {
    ExecProcedure execProcedure = new ExecProcedure();
    execProcedure.setUutSerialNumber(uutSerialNumber);
    execProcedure.setTestProcedure(testProcedure);
    execProcedure.setIterationCount(0);
    em.persist(execProcedure);
    return execProcedure;
  }
}

任何人都知道这有什么问题吗?

谢谢, 杰森

1 个答案:

答案 0 :(得分:2)

EntityManager is not serializable,我想这就是它失败的原因。

来自这里的几个选项:

  • 停用钝化(如果您不需要该机制,最简单的选项)
  • 从SFSB中删除持久性上下文(这很可能会导致您的EXTENDED模式失效)
  • 用Hibernate-Session替换EntityManager, 可序列化(考虑到实验,我自己从未尝试过)