关于多线程和EntityManager的问题

发布于 2024-12-02 04:17:38 字数 876 浏览 0 评论 0原文

我一直在使用 JPA 2.0 实现 EclipseLink 2.2.0 开发我的 Web 应用程序。我终于开始运行多线程代码,并得到了这个异常:

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 方法上使用同步,但我认为这会导致容器(GlassFish)中的线程锁定。

任何建议表示赞赏。

I have been developing my web-app using JPA 2.0 implementation EclipseLink 2.2.0. I finally got around to running multi-threaded code and I got this exception:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

The objects that have all the javax.persistence calls in my application are defined as application scoped, like this:

@Model
@ApplicationScoped
public class LocationControl implements Serializable {

    @PersistenceContext private EntityManager   em;
    @Resource           private UserTransaction utx;

    // etc

And of course all the managed beans (usually RequestScoped or ConversationScoped) that want to access the data base do so like this:

@Inject private LocationControl lc;

So my question is this: Did I get that Exception through the use of @ApplicationScoped DAO? I had thought that it would be more efficient that way, since the container would not have to be continually re-creating this object on every request if it did not have a scope, and the DAO has no state of its own. However if the EntityManager and UserTransaction object have to be separate instances for each user, then that would be a problem.

Alternatively, I could use syncrhonized on the DAO methods, but I think that would cause thread lockups in the container (GlassFish).

Any advice appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亚希 2024-12-09 04:17:38

@Model 注释最初是为了注释请求范围的 beans 而创建的,它的定义如下:

@Named

@RequestScoped

@Stereotype

@Target({TYPE, METHOD, FIELD})

@Retention(RUNTIME)

public @interface Model {}

您当然可以用另一个注释覆盖“@RequestScoped”,但是“@ApplicationScoped”这不是一个好的选择,因为应用程序中的每个人都会修改相同的注入EntityManager。我认为在大多数情况下最好将其保留为@RequestScoped,有时,例如对于登录/注销数据bean“@SessionScoped”可能是一个选项,但我看不到“@ApplicationScoped”dao 的场景。

如果您根本不想使用 @Model 并且使用完整的 Java EE 容器,那么无状态 EJB(正如 BalusC 所说)对于 Dao 来说也是一个不错的选择。

@Model annotation was originally created to annotate request scoped beans, here is how it's defined:

@Named

@RequestScoped

@Stereotype

@Target({TYPE, METHOD, FIELD})

@Retention(RUNTIME)

public @interface Model {}

You can of course override '@RequestScoped' with another annotation but '@ApplicationScoped' it's not a good choice as everyone in the application would modify the state of the same injected EntityManager. I think it would be best to leave it @RequestScoped in most cases, sometimes, for example for a login/logout data bean '@SessionScoped' could be an option but I cannot see a scenario for '@ApplicationScoped' dao.

If you don't want to use @Model at all and you use full Java EE container, then the stateless EJB ,as BalusC said, would be a great option for Dao too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文