我们可以缓存对EntityManager的引用。
至于我们的要求,我们不是将EntityManger注入到其他EJB中,而是使用实用程序类来返回对entitymanager的引用。 问题是每次我们需要获得引用时,我们都在进行JNDI查找。
为了避免JNDI查找,我们想要在hashmap等中缓存对实体管理器的引用。
它似乎有效但我很少有疑问: 1.如果我们缓存entityManager,那么只要引用处于活动状态,它是否会保持连接? 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实体管理器?资源) - 本地实体经理?)。无论如何,答案是......可能。
也许您应该解释当前的工作原理(在开始缓存实体管理器之前)。
我个人衡量事情,我不相信有问题。除非你证明存在问题,否则你要做的就是不值得为此烦恼。