2

我有一个使用容器管理的事务和容器传播的持久性上下文的 Java EE 6 Web 应用程序

@PersistenceContext
private EntityManager em;

在 JPA 层中,我有一个继承策略, whereMyExtendedClassAMyEntendedClassBboth extend abstract MyClass

我使用stateless facade服务类通过方法find, findAll, merge, persist,实现数据访问remove

@Stateless
public class MyExtendedClassAFacade {
    @PersistenceContext
    private EntityManager em;
    public void persist(MyExtendedClassA a) {
        // ...
    }
    // other methods
}

到现在为止还挺好。现在我必须对扩展类的行为实现多态性。这种行为包括管理数据库中的一些其他实体,因此需要 PersistenceContext(因此我需要使用其他StatelessEJB):

@Stateful
public class MyBean {

    @EJB
    private MyClassFacade myClassFacade;   // stateless facade service class

    public void doSomething() {
        for (MyClass c : myClassFacade.findAll()) {
            // here I need to perform operations on the db. 
            // The implementation differs on each extended class.
            // I want to avoid a brute-force coding like:
            if (c.getClass().equals(MyExtendedClassA.class)) {
                @EJB MyExtendedClassAFacade myClassFacadeA;
                myClassFacadeA.doSomething((MyExtendedClassA) c);
            } else if (c.getClass().equals(MyExtendedClassB.class))
                @EJB MyExtendedClassBFacade myClassFacadeB;
                myClassFacadeB.doSomething((MyExtendedClassB) c);
            }
            // Instead, I would like to write something like:
            @EJB AnotherStatelessBean asb;
            asb.doSomething(c);
        }
    }
}

有没有我可以用于这个目标的抽象模式?

4

1 回答 1

3

这是一种 EJB 多态,可以应用于其他情况。它与 JPA 继承没有直接关系。

诀窍是使用@LocalEJB 的接口:

@Local
public interface MyClassFacadeInterface {    
    public void doSomething(MyClass c);
}

并让扩展类的现有 Facade Stateless bean 实现该接口。

之后,stateless必须使用InitialContext.lookup("java:module/MyExtendedClassAFacade"). 在这里,诀窍是给与实体类相关的外观类名称,以便于查找。业务层要使用的代码是:

public void doSomething() {      
    for (MyClass c : myClassFacade.findAll()) {      
        String lookupName = getNameFromClassName(c.getClass().name());
        MyClassFacadeInterface myInt =  (MyClassFacadeInterface) new InitialContex().lookup(lookupName);
        myInt.doSomething(c);
    }      
}      
于 2012-09-20T17:35:38.347 回答