EJB3.1单例+;JPA&x2B;需要JSF设计建议
给定:简单的JSFWebApp(无Seam),JSFbean调用少量EJB,EJB反过来加载并持久化JPA实体。我想要的是为ejb使用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
@Singleton
注释,并插入EntityManager
,而不是EntityManagerFactory
:
@Singleton
public class MyEJB {
@PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
protected EntityManager em; // not EntityManagerFactory
}
规范说,@Singleton
是线程安全的,支持并发和事务属性(从我的pov来看),这使得从JSFbean调用变得安全。由于没有为每个调用重新创建EntityManager
以及它的内部缓存功能,我还期望性能方面的好处
这里我主要关心的是在我有多个单例的情况下,在JPA实体上创建/更新操作,因此,长寿命的EntityManager数量相同
- 如果一个单例更新一个JPA实例会发生什么情况,以及这些情况是如何发生的 是否将更改填充到其他单例
- 由于我无法关闭实体管理器,是否需要刷新它 每个实体更新
- 如果这几个单身汉共享同一个实体会更好吗 经理
- 我只看到了很少的这种设计的例子。为什么?有什么严重的问题吗 缺点
@lock(WRITE)
和@lock(READ)
)可以在一定程度上缓解这种情况
当您希望使用EJB定时器定期执行一段代码,或定期更新缓存等时,单例非常有用
如果一个单例更新一个JPA实例,会发生什么?这些更改是如何填充到其他单例的
不应该与非单例EJB的行为方式有任何不同
由于我无法关闭实体管理器,是否需要在每次实体更新时刷新它
如果您使用CMT,则不会。在每个事务结束时,所有内容都将自动刷新
如果这几个单例共享同一个实体管理器会更好吗
在我看来,这是过早的优化。让容器为您注入EM
我只看到了很少的这种设计的例子。为什么?有什么严重的缺点吗
已经解释过了。关于更改单例EJB的锁类型,我想提一件事。一般来说,这听起来是个好主意,但您应该记住,EntityManger等资源不是线程安全的,因此应该提供适当的并发访问控制。您可以使用@Lock(WRITE)对访问非线程安全资源的方法进行注释,但是如果您的单例EJB的几乎所有接口方法都访问此类资源,那么您将遇到与完全写锁定的方法几乎相同的情况。另一种选择是使用Bean并发管理和手动细粒度同步,但这也是一个值得怀疑的决定
一般来说,正因为如此,我更喜欢无状态EJB而不是单例EJB,并在特定情况下使用后者。这个答案很好,但如果您提到注入的EM实际上是每个事务EM的代理,则可能会消除混淆。请参阅Behrang,特别感谢@Lock。只读操作的性能显著提高,在我的情况下提高了5倍。