0

JPA 2.0 规范在第 6.9 节中提到CriteriaQuery对象是可序列化的,因此可能比任何 openEntityManagerEntityManagerFactory实例的寿命更长:

CriteriaQuery 对象必须是可序列化的。持久性供应商需要支持随后将 CriteriaQuery 对象反序列化为该供应商运行时的单独 JVM 实例,其中两个运行时实例都可以访问任何所需的供应商实现类。

EJB 3.1 规范在第 21.2.2 节中说:

企业 bean 不得使用线程同步原语来同步多个实例的执行,除非它是具有 bean 管理的并发性的单例会话 bean。

CriteriaQuery如果我有一个无状态会话 bean,希望使用CriteriaBuilder从注入的 a 预构建一堆对象@PersistenceContext,我应该将结果存储在哪里?

我可以想到以下可能性,但我担心除了一个之外的所有可能性都与上面的“无同步原语”条款相冲突:

  • 在一个Map存储为我的 bean 实例字段之一的值中,了解我必须同步对地图的访问。我的看法:违反第 21.2.2 节。

  • ConcurrentMap其中存储为我的 bean 实例字段之一的值。我的看法:仍然违反第 21.2.2 节,因为我确信ConcurrentMap实现在某处同步。

  • 在某个@SingletonEJB 的实例字段中,其@Singleton存在只是为了充当这种缓存;使用 bean 管理的并发这应该是合法的,但是现在我所有想要使用此CriteriaQuery缓存的无状态会话 bean 都必须将单例注入到它们自己中......似乎有很多开销。

所以听起来严格来说最后一个选项是唯一符合规范的选项。我对么?

4

1 回答 1

1

我会考虑将它们放在一个简单的静态上下文中,可以从任何地方访问。问题在于初始化它们,因为您需要一个实体管理器实例来执行此操作。可能是用于初始化事物的单例 ejb,如JBoss 启动时 EJB 中的调用方法中所述。单例可以初始化您的条件查询缓存,然后可以通过静态上下文为您的 DAO 提供条件查询。

另一种选择是使用内置支持预编译查询的 JPQL。当然,您会失去使用条件 API 的一些优势,尽管我认为主要问题(类型安全等)可能没问题,因为如果预编译查询在部署时而不是运行时无效,则它们应该抛出异常。

于 2012-06-25T14:26:16.687 回答