This is a pretty newbie question- please know I'm aware of that.
I have a stateless session bean that needs to load up some data once and cache it locally in a static variable for use by all instances of that bean. The data can be accessed through an entity bean. I'm wondering if its safe to cache the entity instance, or if I should clone it. Also, this entity also has sub-entities.
Call the entity Foo. A Foo has a Bar. In my session bean, I'd like to do something like this:
private static final FOO_ID = 123L;
private static Foo foo;
private static Foo getFoo(EntityManager em) {
if (foo != null)
return foo;
return foo = (Foo) em.find(Foo.class, FOO_ID);
}
public void someBusinessMethod() {
EntityManager em = Container.getInstance().getEntityManager();
Foo foo = getFoo(em);
Bar bar = foo.getBar();
// do some stuff with foo and bar
}
My questions:
Is this a bad idea? Will it even work?
Is there a better way to load the Foo data once, possibly without need for that getFoo() method? Doing it statically when the Session class is loaded would seem to be ideal.
New (accurate) sample code, per comments:
public class Foo { // entity
private Long id;
private String name;
// getters and setters
}
public class Bar { // entity
开发者_运维技巧 private Long id;
private String name;
// getters and setters
}
public class FooHelper implements Helper {
private static final long FOO_ID = 123L;
private Foo foo;
public FooHelper() {
// use FOO_ID to look up a Foo & cache it locally
}
@Override
public void addBar(EntityManager em) {
Bar bar = new Bar();
bar.setName(foo.getName());
em.persist(bar);
}
public class StatelesSessionBean {
private static final Helper helper = new FooHelper();
public void someBusinessMethod() {
@PersistenceContext
EntityManager em;
helper.addBar(em);
}
}
Non final static fields are not allowed in Stateless Session Beans (SLSB). From the EJB3 specification, section 21.1.2:
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 there to ensure consistency when distributing instances across multiple JVMs.
So not really a good idea. My suggestion would be to rely on the second level cache that your JPA provider may support and let him handle that transparently.
As a side note, I really wonder why you have this line in your bean:
EntityManager em = Container.getInstance().getEntityManager();
In a managed environment, you should use a container-managed entity manager and get it injected in your SLSB (using the @PersistenceContext
annotation).
精彩评论