【发布时间】:2011-08-30 17:30:49
【问题描述】:
我一直在使用 JPA 2.0 实现 EclipseLink 2.2.0 开发我的网络应用程序。我终于开始运行多线程代码,但遇到了这个异常:
java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.
在我的应用程序中具有所有 javax.persistence 调用的对象被定义为应用程序范围,如下所示:
@Model
@ApplicationScoped
public class LocationControl implements Serializable {
@PersistenceContext private EntityManager em;
@Resource private UserTransaction utx;
// etc
当然,所有想要访问数据库的托管 bean(通常是 RequestScoped 或 ConversationScoped)都是这样做的:
@Inject private LocationControl lc;
所以我的问题是:我是否通过使用 @ApplicationScoped DAO 获得了该异常?我原以为这样会更有效,因为如果容器没有范围,容器就不必在每个请求上不断地重新创建这个对象,并且 DAO 没有自己的状态。但是,如果 EntityManager 和 UserTransaction 对象必须是每个用户的单独实例,那么这将是一个问题。
或者,我可以在 DAO 方法上使用 syncrhonized,但我认为这会导致容器中的线程锁定 (GlassFish)。
任何建议表示赞赏。
【问题讨论】:
-
我不做 CDI,但
LocationControl通常应该是@StatelessEJB 并且将由@EJB注入。我不知道@Model代表什么,但这在商务服务类上是错误的。
标签: jsf-2 glassfish jpa-2.0 glassfish-3 cdi