@Autowired vs @PersistenceContext for EntityManager bean

时间:2015-07-10 07:44:31

标签: spring jpa entitymanager

有什么区别:

@Autowired
private EntityManager em;

@PersistenceContext
private EntityManager em;

这两个选项都适用于我的应用程序,但是我可以使用@Autowired注释来破坏某些内容吗?

5 个答案:

答案 0 :(得分:17)

@PersistenceContext允许您指定要使用的持久性单元。您的项目可能有多个数据源连接到不同的数据库,@PersistenceContext允许您说出要在哪个数据源上运行

在这里查看说明: http://www.coderanch.com/t/481448/java-EJB-SCBCD/certification/unitName-PersistenceContext

答案 1 :(得分:9)

@PersistenceContext是为此特定目的而设计的JPA标准注释。而@Autowired用于Spring中的任何依赖注入。使用@PersistenceContext可让您更好地控制上下文,因为它可让您指定可选元素,例如名称,属性

答案 2 :(得分:8)

<强> @PersistenceContext

返回实体管理器实例

返回容器管理的代理,代表应用程序代码获取和释放存储上下文

答案 3 :(得分:4)

您不应使用@Autowired@PersistenceContext会为每个线程创建唯一的EntityManager。在生产应用程序中,您可以有多个客户端同时调用您的应用程序。对于每个调用,应用程序都会创建一个线程。每个线程应使用其自己的EntityManager。想象一下,如果他们共享相同的EntityManager将会发生什么:不同的用户将访问相同的实体。

usually the EntityManager or Session are bound to the thread (implemented as a ThreadLocal variable).

来源:https://stackoverflow.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注释来执行相同的操作:与JavaEE容器完全一样,为每个线程注入应用程序管理的(=非容器管理的)EntityManager bean。

答案 4 :(得分:0)

您可以创建以下 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 将是一个适当的线程安全代理,因为它会直接在使用字段注入的地方注入(使用 @PersistenceContext)。