The JPA 2.0 specification mentions in section 6.9 that CriteriaQuery
objects are serializable, and hence may outlive any open EntityManager
s or EntityManagerFactory
instances:
CriteriaQuery objects must be serializable. A persistence vendor is required to support the subse- quent deserialization of a CriteriaQuery object into a separate JVM instance of that vendor’s runt- ime, where both runtime instances have access to any required vendor implementation classes.
The EJB 3.1 specification says in section 21.2.2:
An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances, except if it is a Singleton session bean with bean-managed concurrency.
If I have a stateless session bean that wishes to pre-build a bunch of CriteriaQuery
objects using a CriteriaBuilder
obtained from an injected @PersistenceContext
, where should I stash the results?
I can think of the following possibilities but am concerned that all but one run afoul of the "no synchronization primitives" clause above:
In a
Map
that is stored as the value of one of my bean's instance fields, understanding that I'll have to synchronize access to the map. My take: section 21.2.2 violation.In a
ConcurrentMap
that is stored as the value of one of my bean's instance fields. My take: still a section 21.2.2 violation, as I'm sure theConcurrentMap
implementation synchronizes somewhere.In a
@Singleton
EJB's instance field somewhere, where the@Singleton
exists only to serve as this kind of cache; with bean-managed concurrency this should be legal, but now all my stateless session beans that want to make use of thisCriteriaQuery
cache have to inject the singleton into themselves...seems like a lot of overhead.
So it sounds like strictly speaking the last option is the only specification-compliant one. Am I correct?