可以引用javax.persistence.EntityManager进行缓存吗?

时间:2010-09-03 14:30:22

标签: java hibernate jpa ejb-3.0

我们可以缓存对EntityManager的引用。

至于我们的要求,我们不是将EntityManger注入到其他EJB中,而是使用实用程序类来返回对entitymanager的引用。 问题是每次我们需要获得引用时,我们都在进行JNDI查找。

为了避免JNDI查找,我们想要在hashmap等中缓存对实体管理器的引用。

它似乎有效但我很少有疑问: 1.如果我们缓存entityManager,那么只要引用处于活动状态,它是否会保持连接? 2.交易管理会有变化吗?

提前谢谢。

2 个答案:

答案 0 :(得分:2)

EntityManagers不是线程安全的,所以至少你需要通过线程标识符或其他东西来缓存本地线程或地图。

问题1)这是特定于您的底层提供者,但在大多数情况下,是的,打开EntityManager意味着您持有数据库连接。

问题2)可能,但您没有说明您目前使用什么策略进行交易管理。

另一个大问题是,如果您根据规范正确使用EM,则需要处理它并在发生异常时获取新的EM。这意味着您需要在可能出现异常的任何地方正确管理该缓存。

听起来好像你正在尝试将JPA用作JDBC包装器。获取每个单独的SQL语句的新EM然后处理它。您还没有提供有关系统架构的任何信息,也许像View模式中的Open EntityManager这样的中间层可以在不尝试创建新轮的情况下缓解您的问题?

答案 1 :(得分:0)

  

至于我们的要求,我们不是将EntityManger注入到其他EJB中,而是使用实用程序类来返回对entitymanager的引用。

可能有很好的理由,但究竟是什么限制,你为什么不能使用注射?无论如何,查找被识别为一个问题?你测量了什么吗?与总处理时间相比,查找表示多长时间?这是不可忽视的吗?

  

为了避免JNDI查找,我们想要在hashmap等中缓存对实体管理器的引用......

说实话,你在这里提出问题这一事实强烈暗示你不应该这样做。交易管理怎么样?异常处理怎么样(你应该在异常后丢弃EM)?内存管理怎么样?

  

如果我们缓存entityManager,那么只要引用处于活动状态,它是否会保持连接?

资源(只要已经获得)将不会被释放,所以是的。来自Hibernate EM文档:

  

5.1. Entity manager and transaction scopes

     

EntityManagerFactory是一个   昂贵的创建,线程安全的对象   旨在由所有人共享   应用程序线程它被创造了   一次,通常是在应用程序启动时。

     

EntityManager便宜,   应该是非线程安全的对象   一次性使用,用于单个业务   过程,一个单一的工作单位,和   然后丢弃。 EntityManager   不会获得JDBC连接(或   a Datasource)除非需要,   所以你可以安全地打开和关闭   EntityManager即使你不是   确保需要数据访问   满足特定要求*。 (这个   一旦你变得重要,就变得很重要   实施以下一些方面   使用请求拦截的模式。)

     

...

后来:

  

5.2.1. Non-managed environment

     

...

     

close()的调用标志着EntityManager的结束。 close()的主要含义是资源的释放 - 确保您始终关闭并且永远不会保证最终阻止

没有魔力。如果EM需要与数据库交互,它将获得连接。如果您没有close EntityManager,则不会释放此连接。如果需要,请检查底层Hibernate Session的源代码。

  

交易管理会有变化吗?

嗯,您没有说明您目前使用的是什么(容器管理的实体管理器?应用程序管理的实体管理器?)而您没有解释如何管理事务(JTA实体管理器?资源) - 本地实体经理?)。无论如何,答案是......可能。

也许您应该解释当前的工作原理(在开始缓存实体管理器之前)。

我个人衡量事情,我不相信有问题。除非你证明存在问题,否则你要做的就是不值得为此烦恼。