[英]CDI EntityManager injection VS @PersistenceContext entitymanager on an EJB container
当我们在JAVA EE环境中的EntityManager上使用@PersistenceContext注释时,容器将创建entityManagerFactory(我猜测整个会话就是一个),并将为每个请求创建一个新的EntityManager(通过代理它)。
但是在没有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();
}
}
使用CDI的这种方法,会产生相同的效果和性能吗? 在此先感谢您的帮助
“使用CDI的那种方法会产生同样的效果”
不,它不会,使用@ @PersistenceContext
,java EE容器将为每个事务提供不同的entityManager实例。
在这里,您将在每个注入点检索一个可能有问题的唯一实例(em不是线程安全的,而且如果您的数据在其他地方更新,因为相关实体已加载,则持久性上下文状态将与数据库不一致) 。
不,效果不一样。 就像Gab在之前的回答中所说的那样,默认情况下@PersistenceContext
为每个事务注入一个单独的实体管理器。 还可以选择使用EXTENDED持久性上下文 ,但它超出了您的问题范围。
使用您使用CDI提供的代码,您将获得每个注入点的实例,除非您为每个事务创建注入 bean(很可能不是),否则它将不同。
但是,您可以做的是为您的实体管理器使用RequestScoped生成器,如下所示:
public class EntityManagerProducer {
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("livraria");
@Produces
@RequestScoped
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
}
这将在Web应用程序中提供类似的语义,但如果您计划混合使用EJB和非EJB代码,则可能存在一些缺陷,因为此实体管理器不知道正在进行的事务。 其中一些内容包含在此处 。
您还应该检查这个类似的问题使用CDI在Java EE应用程序中获取对EntityManager的引用 ,您可以在这里找到很多关于此问题的优秀讨论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.