我想用EclipseLink和OpenEJB實現描述爲here的DAO模式。鏈接中列出的圖9.1的第一次嘗試正常工作。代碼如下:如何使EntityManager在DAO工廠中正常工作?
// 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);
}
}
然而,當我想以適應工廠模式,我想不出有什麼做的正確方法。我寫的代碼鏈接中的教程,並添加兩個類是這樣的:
// 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異常。當我用調試器跟蹤代碼時,我發現EntityManager
in OracleCustomerDAO
是null
。我認爲這是因爲我沒有在我的新服務中進行任何@EJB
注射,但我不知道我在哪裏可以放入@EJB
注射劑。
那麼注入一個EntityManager與DAO工廠模式的正確方法是什麼?
感謝您的回答,我會閱讀文檔並嘗試修改我的代碼以使其有效(如果我成功,我會接受答案,否則我會在評論中更新狀態)。在模式部分,我讀了很多關於JPA如何殺死DAO的主題,並且對此有不同的看法。我仍然不確定DAO模式是否與JPA一致,也許有一天公司希望擺脫JPA,並且DAO模式將更容易重構,因爲它將邏輯部分和數據操作部分分開了? – Nier
如果您將JPA替換爲其他框架,那麼您的「DAO」抽象將不再可用的機率爲9.99%,您將需要使用它更新DAO接口和業務邏輯。在業務邏輯中替換JPA使用的時間將比自己的DAO花費更多時間。如果你需要在某個地方做一些JPA魔術,你可以在分離的類中抽象這個部分。但JPA使用率的95%是簡單的CRUD,可以直接更新。 – Kazaag
我用'return(CustomerDAO)new InitialContext()。lookup(「java:comp/env/OracleCustomerDAO」)替換'return new OracleCustomerDAO();''getCustomerDAO()''函數。然而,它給了我一個'NamingException',其中說**名稱「comp/env/OracleCustomerDAO」找不到。** – Nier