Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
EJB3.1单例+;JPA&x2B;需要JSF设计建议_Jsf_Jpa_Jsf 2_Ejb 3.0_Ejb 3.1 - Fatal编程技术网

EJB3.1单例+;JPA&x2B;需要JSF设计建议

EJB3.1单例+;JPA&x2B;需要JSF设计建议,jsf,jpa,jsf-2,ejb-3.0,ejb-3.1,Jsf,Jpa,Jsf 2,Ejb 3.0,Ejb 3.1,给定:简单的JSFWebApp(无Seam),JSFbean调用少量EJB,EJB反过来加载并持久化JPA实体。我想要的是为ejb使用@Singleton注释,并插入EntityManager,而不是EntityManagerFactory: @Singleton public class MyEJB { @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME) protected EntityManager em; // not Ent

给定:简单的JSFWebApp(无Seam),JSFbean调用少量EJB,EJB反过来加载并持久化JPA实体。我想要的是为ejb使用
@Singleton
注释,并插入
EntityManager
,而不是
EntityManagerFactory

@Singleton
public class MyEJB {
  @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
  protected EntityManager em; // not EntityManagerFactory
}
规范说,
@Singleton
是线程安全的,支持并发和事务属性(从我的pov来看),这使得从JSFbean调用变得安全。由于没有为每个调用重新创建
EntityManager
以及它的内部缓存功能,我还期望性能方面的好处

这里我主要关心的是在我有多个单例的情况下,在JPA实体上创建/更新操作,因此,长寿命的EntityManager数量相同

  • 如果一个单例更新一个JPA实例会发生什么情况,以及这些情况是如何发生的 是否将更改填充到其他单例
  • 由于我无法关闭实体管理器,是否需要刷新它 每个实体更新
  • 如果这几个单身汉共享同一个实体会更好吗 经理
  • 我只看到了很少的这种设计的例子。为什么?有什么严重的问题吗 缺点
非常感谢

由于EntityManager没有为每个调用重新创建,而且它具有内部缓存功能,因此我还希望获得性能方面的好处

您可能会使用单例节省一些内存,但在应用程序中的任何地方使用它实际上都会使其速度变慢,因为只有一个EJB来服务应用程序的不同用户的所有并发请求,所以容器会锁定对EJB的访问,当它忙于服务一个请求时,就不能服务另一个请求。但是,使用锁类型(即
@lock(WRITE)
@lock(READ)
)可以在一定程度上缓解这种情况

当您希望使用EJB定时器定期执行一段代码,或定期更新缓存等时,单例非常有用

如果一个单例更新一个JPA实例,会发生什么?这些更改是如何填充到其他单例的

不应该与非单例EJB的行为方式有任何不同

由于我无法关闭实体管理器,是否需要在每次实体更新时刷新它

如果您使用CMT,则不会。在每个事务结束时,所有内容都将自动刷新

如果这几个单例共享同一个实体管理器会更好吗

在我看来,这是过早的优化。让容器为您注入EM

我只看到了很少的这种设计的例子。为什么?有什么严重的缺点吗


已经解释过了。

关于更改单例EJB的锁类型,我想提一件事。一般来说,这听起来是个好主意,但您应该记住,EntityManger等资源不是线程安全的,因此应该提供适当的并发访问控制。您可以使用@Lock(WRITE)对访问非线程安全资源的方法进行注释,但是如果您的单例EJB的几乎所有接口方法都访问此类资源,那么您将遇到与完全写锁定的方法几乎相同的情况。另一种选择是使用Bean并发管理和手动细粒度同步,但这也是一个值得怀疑的决定


一般来说,正因为如此,我更喜欢无状态EJB而不是单例EJB,并在特定情况下使用后者。

这个答案很好,但如果您提到注入的EM实际上是每个事务EM的代理,则可能会消除混淆。请参阅Behrang,特别感谢@Lock。只读操作的性能显著提高,在我的情况下提高了5倍。