注入 EntityManager vs. EntityManagerFactory

2022-08-31 14:02:35

一个很长的问题,请忍受我。

我们正在将Spring + JPA用于Web应用程序。我的团队正在讨论注入(基于泛型的DAO,由APPFUSE提供的行,我们出于某种原因不使用)注入。我们使用的是“应用程序托管持久性”。EntityManagerFactoryGenericDAOJpaDaosupportEntityManager

反对注入a的论点是它太重了,所以不是必需的,它做了我们需要的。此外,由于Spring会为每个Web请求创建一个新的DAO实例(我对此表示怀疑),因此不会有任何并发问题,因为在同一实例中由两个线程共享。EntityManagerFactoryEntityManagerEntityManager

注入EFM的论点是,这是一种很好的做法,毕竟有一个工厂的手柄总是好的。

我不确定哪种是最好的方法,有人可以启发我吗?


答案 1

注入EntityManagerFactory与EntityManager的利弊都在这里的Spring文档中详细说明,我不确定我是否可以改进这一点。

话虽如此,您的问题中有一些要点应该得到解决。

...Spring将为每个Web请求创建一个新的DAO实例...

这是不正确的。如果你的 DAO 是一个 Spring bean,那么它就是一个单例,除非你通过 Bean 定义中的属性来配置它。为每个请求实例化 DAO 将是疯狂的。scope

注入EMF的论点是,这是一种很好的做法,毕竟有一个工厂的手柄总是好的。

这个论点并不成立。一般的良好实践是,应该为对象注入完成其工作所需的最少协作者。


答案 2

我正在放下我最终收集到的东西。从春季参考中的“基于普通 JPA 实现 DAO”一节中:

尽管 EntityManagerFactory 实例是线程安全的,但 EntityManager 实例不是。注入的 JPA EntityManager 的行为类似于从应用程序服务器的 JNDI 环境中获取的 EntityManager,如 JPA 规范所定义。它将所有调用委托给当前事务性实体管理器(如果有);否则,它将回退到每个操作新创建的 EntityManager,实际上使其使用线程安全。

这意味着根据JPA规范,EntityManager实例不是线程安全的,但是如果Spring处理它们,它们就是线程安全的。

如果您使用的是Spring,最好注入EntityManagers而不是EntityManagerFactory。


推荐