在会话结束后安全存储对Entity Bean的引用?

时间:2010-07-09 16:39:42

标签: java jpa java-ee ejb-3.0 stateless-session-bean

这是一个非常新手的问题 - 请知道我知道这一点。

我有一个无状态会话bean,需要加载一些数据并将其本地缓存在一个静态变量中,供该bean的所有实例使用。可以通过实体bean访问数据。我想知道缓存实体实例是否安全,或者我是否应该克隆它。此外,该实体也有子实体。

调用实体Foo。 Foo有一个酒吧。在我的会话bean中,我想做这样的事情:

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
}

我的问题:

  1. 这是个坏主意吗?它会工作吗?

  2. 有没有更好的方法来加载Foo数据一次,可能不需要那个getFoo()方法?在加载Session类时静态地执行它似乎是理想的。

  3. 新的(准确的)示例代码,每条评论:

    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);
        }
    }
    

1 个答案:

答案 0 :(得分:2)

无状态会话Bean(SLSB)中不允许使用非最终静态字段。从EJB3规范,第21.1.2节:

  

企业bean不得使用读/写静态字段。允许使用只读静态字段。因此,建议将企业bean类中的所有静态字段声明为final。

此规则用于确保在跨多个JVM分发实例时的一致性。

所以不是一个好主意。我的建议是依靠你的JPA提供者可能支持的二级缓存,让他透明地处理它。

作为旁注,我真的想知道为什么你的bean中有这一行:

EntityManager em = Container.getInstance().getEntityManager();

在托管环境中,您应该使用容器管理的实体管理器并将其注入SLSB(使用@PersistenceContext注释)。