简体   繁体   English

在EJB容器上的CDI EntityManager注入VS @PersistenceContext实体管理器

[英]CDI EntityManager injection VS @PersistenceContext entitymanager on an EJB container

When we use the @PersistenceContext annotation on an EntityManager in a JAVA EE environment, the container will create the entityManagerFactory (one for the whole session i guess) and will create a new EntityManager for each request ( by proxying it). 当我们在JAVA EE环境中的EntityManager上使用@PersistenceContext注释时,容器将创建entityManagerFactory(我猜测整个会话就是一个),并将为每个请求创建一个新的EntityManager(通过代理它)。

But using CDI without a JAVA EE container i saw something like this: 但是在没有JAVA EE容器的情况下使用CDI我看到了这样的事情:

public class EntityManagerProducer {
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("livraria");

    @Produces  
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void close(EntityManager em) {
    em.close();
}

} }

Using that approach with CDI, will have the same effect and performance? 使用CDI的这种方法,会产生相同的效果和性能吗? Thanks in advance for any help 在此先感谢您的帮助

"Is using that approach with CDI will have the same effect" “使用CDI的那种方法会产生同样的效果”

No it won't, using @PersistenceContext the java EE container will provide you a different entityManager instance for each transaction. 不,它不会,使用@ @PersistenceContext ,java EE容器将为每个事务提供不同的entityManager实例。

Here you will retrieve an unique instance at each injection point which can be problematic (em is not thread safe, moreover the persistence context state will not be consistent with the database one if your data are updated somewhere else since the related entity have been loaded). 在这里,您将在每个注入点检索一个可能有问题的唯一实例(em不是线程安全的,而且如果您的数据在其他地方更新,因为相关实体已加载,则持久性上下文状态将与数据库不一致) 。

No, the effect is not the same. 不,效果不一样。 Like Gab said in a previous answer, @PersistenceContext by default injects a separate entity manager per transaction. 就像Gab在之前的回答中所说的那样,默认情况下@PersistenceContext为每个事务注入一个单独的实体管理器。 There is also an option to use an EXTENDED persistence context , but its beyond the scope of your question. 还可以选择使用EXTENDED持久性上下文 ,但它超出了您的问题范围。

With the code that you provided using CDI you would get an instance per injection point which is not the same unless you create the injecting bean for each transaction (most likely not). 使用您使用CDI提供的代码,您将获得每个注入点的实例,除非您为每个事务创建注入 bean(很可能不是),否则它将不同。

However, what you can do is to use a RequestScoped producer for your entity manager, like so: 但是,您可以做的是为您的实体管理器使用RequestScoped生成器,如下所示:

 public class EntityManagerProducer {
     private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("livraria");

     @Produces
     @RequestScoped
     public EntityManager getEntityManager() {
         return emf.createEntityManager();
     }
 }

This will give you a similar semantics in a web application, but there may be some pitfalls if you plan to mix EJB and non-EJB code, since this entity manager is not aware of the transactions in progress. 这将在Web应用程序中提供类似的语义,但如果您计划混合使用EJB和非EJB代码,则可能存在一些缺陷,因为此实体管理器不知道正在进行的事务。 Some of this is covered here . 其中一些内容包含在此处

You should also check this similar question Getting a reference to EntityManager in Java EE applications using CDI where you can find a lot of excellent discussion on the matter. 您还应该检查这个类似的问题使用CDI在Java EE应用程序中获取对EntityManager的引用 ,您可以在这里找到很多关于此问题的优秀讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM