EntityManager bean 的 @Autowired 与 @PersistenceContext
Posted
技术标签:
【中文标题】EntityManager bean 的 @Autowired 与 @PersistenceContext【英文标题】:@Autowired vs @PersistenceContext for EntityManager bean 【发布时间】:2015-09-28 20:59:44 【问题描述】:有什么区别:
@Autowired
private EntityManager em;
对比:
@PersistenceContext
private EntityManager em;
这两个选项都可以在我的应用程序中使用,但我可以通过使用 @Autowired
注释来破坏某些内容吗?
【问题讨论】:
【参考方案1】:您可以创建以下FactoryBean
以使EntityManager
可正确注入,即使是通过构造函数注入:
/**
* Makes the @link EntityManager injectable via <i>@Autowired</i>,
* so it can be injected with constructor injection too.
* (<i>@PersistenceContext</i> cannot be used for constructor injection.)
*/
public static class EntityManagerInjectionFactory extends AbstractFactoryBean<EntityManager>
@PersistenceContext
private EntityManager entityManager;
@Override
public Class<?> getObjectType()
return EntityManager.class;
@Override
protected EntityManager createInstance()
return entityManager;
请注意,因为我们在内部使用了@PersistenceContext
注解,所以返回的EntityManager
将是一个适当的线程安全代理,因为它会通过字段注入直接在使用位置注入(使用@987654326 @)。
【讨论】:
【参考方案2】:你不应该使用@Autowired
。
@PersistenceContext
负责为每个线程创建一个唯一的 EntityManager。在生产应用程序中,您可以有多个客户端同时调用您的应用程序。对于每次调用,应用程序都会创建一个线程。每个线程都应该使用自己的 EntityManager。想象一下如果他们共享同一个 EntityManager 会发生什么:不同的用户将访问同一个实体。
usually the EntityManager or Session are bound to the thread (implemented as a ThreadLocal variable).
来源:https://***.com/a/42074452/2623162
EntityManager instances are not thread-safe.
来源:https://docs.oracle.com/cd/E19798-01/821-1841/bnbqy/index.html
请注意@PersistenceContext
注解来自javax.persistence
包,而不是来自spring 框架。在 JavaEE 中,JavaEE 容器(也称为应用服务器)使用它来注入 EntityManager。 Spring 借用 PersistenceContext 注释来做同样的事情:为每个线程注入一个 application-managed(= 不是 container-managed)EntityManager bean,就像 JavaEE 容器一样。
【讨论】:
我可以在谈论线程时确认这一点。例如,如果没有 @PersistenceContext,我的应用程序会在其他线程中运行 SQL 插入/更新,但不会对数据库进行任何更改。【参考方案3】:@PersistenceContext:
不返回实体管理器实例
它返回代表应用程序代码获取和释放存在上下文的容器管理代理
【讨论】:
【参考方案4】:@PersistenceContext
允许您指定要使用的持久性单元。您的项目可能有多个数据源连接到不同的数据库,@PersistenceContext
允许您说出要操作的数据源
查看这里的解释: http://www.coderanch.com/t/481448/java-EJB-SCBCD/certification/unitName-PersistenceContext
【讨论】:
【参考方案5】:@PersistenceContext
是为特定目的设计的JPA 标准注释。而 @Autowired
用于 Spring 中的任何依赖注入。使用 @PersistenceContext
可以让您更好地控制上下文,因为它使您能够指定可选元素,例如名称、属性
【讨论】:
这个我知道,但是对应用有什么影响呢?考虑使用 Spring 的标准 @Transactional。使用 @Autowired 时,会发生与使用 @PersistenceContext 相同的行为,并且每个应用程序事务都有 em? 我认为使用@PersistenceContext
通常是最佳实践,因为它更准确地描述了您尝试实现的依赖注入类型。此外,它还提供了专门用于 EntityManager 的可选参数,这在您拥有多个 EntityManager 时会很有用。从功能上讲,我相信您可以使用 @Autowired
实现相同的注入,但我建议您使用旨在像这样使用的注释。以上是关于EntityManager bean 的 @Autowired 与 @PersistenceContext的主要内容,如果未能解决你的问题,请参考以下文章
在条件下在无状态会话 Bean 中注入特定的 EntityManager
JPA 数据存储库 - 找到 2 个 EntityManager 类型的 bean
考虑在你的配置中定义一个“javax.persistence.EntityManager”类型的bean
EntityManager bean 的 @Autowired 与 @PersistenceContext
Spring JPA/Hibernate EmptyInterceptor 不注入 Entitymanager/Spring bean