2016-04-07 11 views
0

EclipseLinkとOpenEJBでhereというDAOパターンを実装したいと思います。リンクにリストされている図9.1の最初の試行はうまく動作します。DAOファクトリでEntityManagerを正しく動作させる方法は?

// 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パターンを適用したい場合、私はそれを行うための正しい方法は何把握することはできませんコードは次のようです。私は、リンク内のチュートリアルとして、コードを書き、このように2つのクラスを追加します。

// 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がを与えます。デバッガでコードをトレースすると、EntityManagerOracleCustomerDAOnullです。私はそれが私の新しいサービスで@EJB注射をしなかったからだと思うが、私はどこにその@EJB注射を置くことができるのか分からない。

したがって、DAOファクトリパターンを持つEntityManagerを挿入する適切な方法は何ですか?

答えて

1

EJBがEJBのように動作するためには、作成しないでください。 EJBコンテナは、すべての装飾(トランザクション、インジェクション)が正しく適用されていることを確認するために、それらを作成する責任があります。

EJBコンテナは、すでに工場パターンを実装しています。その機能を使用して特定の実装を取得する必要があります(私はスタンドアロンのopenEJBでは経験はありませんが、完全なJava EE環境ではCDIとJNDIが必要な機能を提供しています)。

予想されるEJBを取得するためにJNDIを使用できるはずです。 CDIの方法について

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

full doc

、あなたはその代替メカニズム(TommEE doc)を使用することができます。

このコードは、EJBの名前は、デフォルトではクラス名であれば動作するはずです。

パターンについての少しの言葉。彼らは、痛みポイントを修正するために使用する必要があります。 J2EEのパターンは、J2EEの限界を克服するために文書化されています。 Java EEの将来のリリースでは、イベントでより使いやすい方法で異なるパターンを実装する要素を導入しています。 JAPはその一部です。

JPAは、Domain Store patternの実装です。ドメインストアの図では、既にDAOが含まれていることがわかります。だからすでにDAOを含む抽象化の上にDAOを作成するという点は何ですか?

+0

答えをいただきありがとうございます。私はドキュメントを読んでコードを修正して動作させます(成功した場合は回答を受け入れるか、コメントのステータスを更新します)。パターン部分では、JPAがどうやってDAOを殺したのか、それについて何かを話しましたが、これについては多くの意見があります。私はまだDAOパターンが良いかどうかJPAで、たぶんJPAを取り除きたいと思うかもしれませんし、DAOパターンは論理部分とデータ操作部分を分けるのでリファクタリングが簡単でしょうか? – Nier

+0

JPAを他のフレームワークに置き換えた場合、9.99%の確率で "DAO"抽象化はもう機能しなくなり、DAOインターフェイスとそれを使用するビジネスロジックを更新する必要があります。 DAOよりもビジネスロジックのJPAの使用を置き換えるのに時間がかかります。いくつかのJPAマジックをどこかでやる必要があるならば、この部分を別のクラスで抽象化することができます。しかし、JPAの95%は単純なCRUDであり、これは簡単に更新できます。 – Kazaag

+0

'return new OracleCustomerDAO();'を 'getCustomerDAO()'関数の 'return(CustomerDAO)new InitialContext()。lookup(" java:comp/env/OracleCustomerDAO ");に置き換えました。しかし、それは私に 'Name =" comp/env/OracleCustomerDAO "が見つからないという' NamingException'を返します。** – Nier

関連する問題