注入EntityManagerVs。实体管理器工厂


70

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

我们将Spring + JPA用于Web应用程序。我的团队在讨论如何在注入EntityManagerFactoryGenericDAO(基于泛型的东西对AppFuse中提供的线DAO,我们不使用JpaDaosupport某种原因)在注入EntityManager。我们正在使用“应用程序管理的持久性”。

反对注入a的论点EntityManagerFactory是它太重了,因此不是必需的,这EntityManager就是我们需要的。另外,由于Spring会为每个Web请求创建一个DAO的新实例(我对此表示怀疑),因此不会像以前那样存在任何并发问题EntityManager实例中,两个线程共享该线程。

注入EFM的理由是,对于拥有工厂的人来说,EFM的良好实践总会带来好处。

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


3
我进一步了解到,当Spring注入EntityManager时,它是“容器管理的持久性”,并且Spring还使Entitymanagers线程安全。SB
SB。

Answers:


51

Spring文档在此处详细说明了注入EntityManagerFactory与EntityManager的优缺点,我不确定是否可以对此进行改进。

话虽如此,您的问题中有一些要澄清的地方。

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

这是不正确的。如果您的DAO是Spring bean,则它是单例,除非您通过scopebean定义中的属性对其进行了配置。为每个请求实例化一个DAO会很疯狂。

注入EMF的理由是,对于拥有工厂的控制权而言,这是一种良好的实践做法。

这种说法并没有真正成立。一般的良好做法是,应向对象注入完成工作所需的最少协作者。


1
如果您不能改善他们的解释,您可以解释一下吗?该文档中有很多内容,但我还没有完全看到它的“说明”。此外,最好有一个可以独立存在的答案,而不需要人们通过链接查看完整的答案。
贾斯珀,

26

我放下我终于收集到的东西。从部分“基于原生的JPA实现DAO在Spring参考”:

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

这意味着按照JPA规范,EntityManager实例不是线程安全的,但是如果Spring处理它们,则将它们设置为线程安全的。

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


9

我认为这已经被很好地涵盖了,但是只是为了强调几点。

  • 如果DAO由Spring注入,则默认情况下为单例。您必须将范围明确设置为原型,才能每次创建一个新实例。

  • @PersistenceContext注入的实体管理器是线程安全的

话虽如此,我在多线程应用程序中确实遇到了单例DAO的问题。我最终使DAO成为实例化的bean,从而解决了该问题。因此,尽管文档可能只是一句话,但您可能希望彻底测试应用程序。

跟进:

我认为部分问题是我正在使用

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

如果使用PersistenceContextType.EXTENDED,请记住,如果我理解正确,则必须手动关闭事务。看到这个主题以获取更多信息。

另一跟进:

使用实例化的DAO是一个非常糟糕的主意。DAO的每个实例将具有其自己的持久性缓存,并且对一个缓存的更改将不会被其他DAO Bean识别。对不起,不好的建议。


7

我发现在我们的DAO上设置@Repository Spring注释,并由Spring管理并由@PersistenceContext注释注入的EntityManager是使所有内容流畅运行的最便捷方法。您将从共享EntityManager和异常转换的线程安全中受益。默认情况下,如果您组合了一个管理器中的多个DAO,则共享的EntityManager将管理事务。最后,您会发现您的DAO会变得贫血。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.