The restriction of using static field and synchronization is stated in EJB 3.0 spec chapter 21.1.2. It also explains why.
• An enterprise bean must not use read/write static fields. Using
read-only static fields is allowed. Therefore, it is recommended that
all static fields in the enterprise bean class be declared as final.
This rule is required to ensure consistent runtime semantics because
while some EJB containers may use a single JVM to execute all
enterprise bean’s instances, others may distribute the instances
across multiple JVMs.
• An enterprise bean must not use thread
synchronization primitives to synchronize execution of multiple
instances.
This is for the same reason as above. Synchronization would not work
if the EJB container distributed enterprise bean’s instances across
multiple JVMs.
If you implement a cache by singleton POJO, you may have the risk that actually there are multiple cache instances in each JVM if EJB container distributed EJB instances across multiple JVMs, for instance, in a cluster environment.
So it depends,
- If the application isn't deployed in cluster environment, you could do that. As far as I know, WebLogic and GlassFish run one server instance in one JVM.
- If data consistency is not restrictedly needed, you could also do that. Usually it's allowed when talking about "cache".
If it doesn't work for you, probably you should think about caching data outside of EJB container, e.g. put in Redis or Hazelcast.