如何使EntityManager在DAO工厂中正常工作



我想用EclipseLink和OpenEJB实现这里描述的DAO模式。链接中列出的图9.1的第一次尝试效果良好。代码如下:

// CustomerDAO
@Local
public interface CustomerDAO {
    Customer findCustomer(String id);
}
// OracleCustomerDAO
@Stateless
@Local(CustomerDAO.class)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class OracleCustomerDAO implements CustomerDAO {
    @PersistenceContext(unitName = "MY_EJB")
    private EntityManager em;
    public Customer findCustomer(String id) {
        return em.find(Customer.class, id);
    }
}

为我服务:

public class CustomerService implements CustomerServiceLocal {
    @EJB
    CustomerDAO customerDAO;
    public Customer findCustomer(String id) {
        return customerDAO.findCustomer(id);
    }
}

然而,当我想适应Factory模式时,我不知道什么是正确的方法

// DAOFactory
public abstract class DAOFactory {
    public abstract CustomerDAO getCustomerDAO();
    public enum Factory {
        ORACLE;
    }
    public static DAOFactory getDaoFactory(Factory whichFactory) {
        switch (whichFactory) {
        case ORACLE:
            return new OracleDAOFactory();
            break;
        default:
            break;
        }
    }
}
// OracleDAOFactory
public class OracleDAOFactory extends DAOFactory {
    @Override
    public CustomerDAO getCustomerDAO() {
        return new OracleCustomerDAO();
    }
}

我将我的服务修改为:

public class CustomerService implements CustomerServiceLocal {
    public Customer findCustomer(String id) {
        CustomerDAO customerDAO = DAOFactory.getDaoFactory(Factory.ORACLE).getCustomerDAO();
        return customerDAO.findCustomer(id);
    }
}

这给了我一个NullPointerException。当我使用调试器跟踪代码时,我发现OracleCustomerDAO中的EntityManagernull。我想这是因为我在新服务中没有进行任何@EJB注入,但我不知道@EJB注入可以放在哪里。

那么,用DAO工厂模式注入EntityManager的正确方法是什么呢?

为了让EJB像EJB一样工作,您不应该创建它们。EJB容器负责创建它们,并确保每个装饰(事务、注入)都正确应用。

EJB容器已经在为您实现工厂模式。您应该使用它的功能来获得特定的实现(我没有独立的openEJB的经验,但在完整的JavaEE环境中,CDI和JNDI提供了所需的功能)。

看来您应该能够使用JNDI来检索期望的EJB。

如果EJB的名称默认为类名:,则此代码应该有效

CustomerDAO friend = (CustomerDAO) new InitialContext().lookup("java:comp/env/OracleCustomerDAO");

(完整文档)

对于CDI方式,您可以使用它的替代机制(TommEE-doc)。

关于图案的一个小词。它们应该用来解决一个痛点。J2EE模式已经被记录下来以克服J2EE的局限性。在JavaEE的未来版本中,他们引入了以事件更可用的方式实现不同模式的元素。日本是其中的一部分。

JPA是域存储模式的一种实现。在DomainStore图中,您可以清楚地看到它已经包含了DAO。那么,在已经包含DAO的抽象之上创建DAO有什么意义呢?

最新更新