JPA EntityManager静态还是实例? [英] JPA EntityManager Static or Instance?

查看:266
本文介绍了JPA EntityManager静态还是实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去我使用了一个JPA实例,它使用了DAO的实例 javax.persistence.EntityManager ;这是大多数例子的设置方式。

  public class BaseDaoThatEveryDaoExtends {
@PersistenceContext
private EntityManager entityManager;
}

我刚刚发现了一个使用 static 通过 PersistenceContext 注释注入, > javax.peristence.EntityManger ,建筑师告诉我这不会造成任何问题,即使在使用JTA和XA数据源的集群应用程序中也有问题:

  public class BaseDaoThatEveryDaoExtends {
@PersistenceContext
private static EntityManager entityManager;
}

据我所知,这是一种反模式,因为 EntityManager 包含一些状态信息并使其成为静态,这使整个状态应用程序变得广泛。这也使得这些类非常难以测试。



这样做是否存在其他缺点,或者这是使用 EntityManager ?的标准方式?

解决方案

我认为主要风险并不在EntityManager本身,而是在使用时附加到实体管理器的应用程序上下文中。假设您有两个不同的客户端向您的服务器发出请求,这两个客户端都调用了您的应用程序的两种不同的方法,它们都运行在不同的线程上,但都使用相同的实体经理。

据我所知,实体管理器将附加一个上下文,这个上下文将由两个客户共享。每次将实例加载到上下文时,都将通过共享实体管理器提供给线程。如果他们篡改彼此的数据会发生什么?如果他们使用不同的事务隔离配置会发生什么?如何确保客户端1不会改变客户端2当前使用的数据?



如果其中一个客户端使上下文无效,另一个客户端会做什么?你如何处理这种并发性?


I've built some JPA stuff in the past that used an instance of the javax.persistence.EntityManager per instance of DAO; this is the way most examples are setup.

public class BaseDaoThatEveryDaoExtends {
   @PersistenceContext
   private EntityManager entityManager;
}

I've just stumbled upon code that uses a static javax.peristence.EntityManger injected by a PersistenceContext annotation, the architect tells me this causes no problems and they never had any problem even in a clustered application with JTA and an XA data source:

public class BaseDaoThatEveryDaoExtends {
   @PersistenceContext
   private static EntityManager entityManager;
}

As far as I can tell this is an anti-pattern as the EntityManager holds some state information and making it static makes that whole state application wide. Also this makes the classes very hard to test.

Are there other drawbacks to doing this or is this a standard way of using an EntityManager ?

解决方案

I think the major risk is not in the EntityManager itself, but in the application context that is attached to the entity manager when it is used.

Let's assume you have two different clients making a request to your server, both invoking two different methods of your application, both running on different threads, but both using the same entity manager.

As far as I know the entity manager will have a single context attached to it, this context will be shared by both clients. Every time you load an instance to the context, will be available to threads through the shared entity manager. What will happen if they tamper with each other's data? What will happen if they are using different transaction isolation configuration?. How can you possibly be sure that client 1 is not altering data being currently used by client 2?

What if one of the clients invalidates the context, what will the other do? How do you deal with concurrency this way?

这篇关于JPA EntityManager静态还是实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆