2016-04-07 34 views
0

EclipseLink ve OpenEJB ile here açıklanan DAO desenini uygulamak istiyorum. Bağlantıda listelenen Şekil 9.1 ile ilk deneme iyi çalışıyor.EntityManager, DAO Fabrikalarında nasıl düzgün çalışır?

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

Ve Hizmetimde: Ancak

public class CustomerService implements CustomerServiceLocal { 
    @EJB 
    CustomerDAO customerDAO; 

    public Customer findCustomer(String id) { 
     return customerDAO.findCustomer(id); 
    } 
} 

, ben Fabrika deseni uyarlamak istediğinizde, bunu yapmak için doğru yolu ne olduğunu anlamaya olamaz kod gibidir. Ben linkte öğretici olarak kod yazdım ve bunun gibi iki sınıf ekleme:

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

} 

Ve bu benim hizmetini değiştirin:

public class CustomerService implements CustomerServiceLocal { 

    public Customer findCustomer(String id) { 

     CustomerDAO customerDAO = DAOFactory.getDaoFactory(Factory.ORACLE).getCustomerDAO(); 

     return customerDAO.findCustomer(id); 
    } 
} 

Ve bu bana NullPointerException verir. Kod hata ayıklayıcı ile izlediğimde, OracleCustomerDAO içinde EntityManagernull olduğunu buldum. Yeni servisimde hiç @EJB enjeksiyon yapmadığım için düşünüyorum, ancak @EJB enjeksiyonunu nereye koyabileceğime dair hiçbir fikrim yok.

Bir EntityManager'ı DAO Factories Kalıbı ile enjekte etmenin uygun yolu nedir?

cevap

1

EJB'nin EJB gibi davranması için bunları oluşturmamalısınız. EJB konteynırı, her bir dekorasyonun (işlem, enjeksiyon) doğru şekilde uygulandığından emin olmaktan sorumludur.

EJB konteyneri zaten sizin için fabrika modelini uyguluyor. Özel bir uygulama elde etmek için işlevselliğini kullanmalısınız (tek başına openEJB ile deneyimlemedim, ancak tam bir Java EE ortamında CDI ve JNDI gerekli işlevselliği sağlıyor).

Beklenen EJB'yi almak için JNDI kullanabilmeniz gerekir.

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

(full doc) CDI yolu için

, onun alternatif bir mekanizma (TommEE doc) kullanabilirsiniz: EJB adı sınıf adı varsayılan olarak ise

Bu kod çalışması gerekir.

Desenlerle ilgili küçük bir kelime. Bir ağrı noktasını düzeltmek için kullanılmalılar. J2EE kalıpları J2EE'nin sınırlandırılması için belgelenmiştir. Java EE'nin gelecekte piyasaya sürülmesinde, bir olaydaki farklı modeli daha kullanışlı bir şekilde uygulayan unsurlar sunarlar. JAP bunun bir parçası.

JPA, Domain Store pattern'un bir uygulamasıdır. Domain Store şemasında, zaten DAO içerdiğini açıkça görebilirsiniz. Öyleyse, DAO'yu içeren bir soyutlamanın üstüne DAO yaratmanın amacı nedir?

+0

Cevabınız için teşekkürler. Dokümanları okuyacağım ve çalışmam için kodumu değiştirmeye çalışacağım (ve başarılı olursam cevabı kabul edeceğim, yoksa durumu yorum olarak güncelleyeceğim). Desen bölümünde, JPA'nın DAO'yu nasıl öldürdüğü ya da bunun gibi bir şey hakkında pek çok konu okudum ve bunun hakkında birçok farklı görüş var. Yine de, DAO modelinin JPA ile iyi ya da emin olmadığından emin değilim, belki bir gün şirket JPA'dan kurtulmak istiyor ve DAO modeli, mantıksal bölümü ve veri işleme bölümünü ayırması nedeniyle daha kolay anlaşılabiliyor mu? – Nier

+0

JPA'yı başka bir çerçeveyle değiştirirseniz, "DAO" özetinizin artık çalışmadığı% 9.99 ve DAO arabirimlerini ve iş mantığını kullanarak güncelleştirmeniz gerekir. İş mantığındaki JPA kullanımının kendisinin DAO'sundan daha fazla zaman alacaktır. Biraz JPA büyüsü yapmanız gerekiyorsa, bu bölümü ayrı bir sınıfta soyutlayabilirsiniz. Ancak JPA kullanımının% 95'i, güncellenmesi kolay olan basit CRUD'lardır. – Kazaag

+0

'getCustomerDAO() 'işlevindeki' return '(customerdao) yeni InitialContext() .özelimi (" java: comp/env/OracleCustomerDAO ") ile yeni OracleCustomerDAO(); Ancak bana "ad/comp/env/OracleCustomerDAO" bulunmayan bir 'NamingException 'veriyor. ** – Nier