私は基本的に、新しいWebアプリで作業を開始する初心者です。webappは、ほとんどの場合、基本的なCRUD操作です。このために、永続性プロバイダーとしてHibernateでJPAを使用することを決定し、開発とテストの目的でApacheDerbyで開発する予定です。私は、EJB3BeanをデプロイするためのアプリケーションサーバーとしてGlassFishv2を使用しています。フロントエンドにはJSF(NeatBeansv6.5にバンドルされているwoodstockテーマのVisualJSF)を使用しています
これが私がこれまで進めてきた方法です。私はほとんどの場合、NetBeans 6.5ウィザードを使用して、エンティティクラスとejbセッションBeanを生成しています。私がしていることは、ApacheDerbyで新しいテーブル(XXXなど)を作成することです。次に、「データベースのエンティティクラス」を使用して、必要なすべてのアノテーションとゲッターおよびセッターメソッドを含むXXXエンティティクラスを生成します。
次に、「エンティティクラスからのJPAコントローラクラス」ウィザードを実行して、基本的に次のものを含むコントローラクラスコードXXXJpaControllerを生成します。
@Resource private UserTransaction utx = null;
@PersistenceUnit(unitName = "TestEnterpriseApplication-ejbPU") private EntityManagerFactory emf = null;
1. EntityManager getEntityManager() { return emf.createEntityManager() }
2. void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception{}
3. void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{}
4. void destroy(Long id) throws NonexistentEntityException, RollbackFailureException, Exception {}
5. List<XXX> findXXXEntities(){}
6. List<XXX> findXXXEntities(int maxResults, int firstResult) {}
7. List<XXX> findXXXEntities(boolean all, int maxResults, int firstResult){}
8. XXX findXXX(Long id){}
9. int getXXXCount(){}
次に、「エンティティクラスのセッションBean」ウィザードを実行して、次のように必要なときにフロントエンドから呼び出すことができるEntityFacadeローカル/リモートセッションBeanを生成します。
@PersistenceContext private EntityManager em;
1. void create(XXX xxx) { em.persist(xxx); }
2. void edit(XXX xxx) { em.merge(xxx); }
3. void remove(XXX xxx) { em.remove(em.merge(xxx)); }
4. List<XXX> findAll() { return em.createQuery("select object(o) from XXX as o").getResultList(); }
私はすでにtryとcatchとtransactionsをよりよくサポートするこれらのメソッドを実装するgeneratdControllerクラスを持っているので、以下に示すように、代わりにXXXFacade.javaでそれを呼び出すことにしました。
XXXJpaController XXXController = new XXXJpaController();
1. public void create(XXX xxx) throws PreexistingEntityException, RollbackFailureException, Exception {
XXXController.create(xxx); }
2. public void edit(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
XXXController.edit(xxx); }
3. public void remove(XXX xxx) throws NonexistentEntityException, RollbackFailureException, Exception{
XXXController.destroy(xxx.getId()); }
4. public XXX find(Object id) {
return XXXController.findXXX((Long)id); }
5. public List<XXX> findAll() {
return XXXController.findXXXEntities(); }
これが私の最初の質問です。これはJEEの世界で物事を行う正しい方法ですか、それともそれを行うためのより良い方法がありますか?ここで何らかの冗長性を導入していますか?これは、私がすべてのエンティティクラスでほぼ従ってきたパターンです。エンティティクラスの作成->コントローラクラスの作成->entityfacadeクラスの作成->entityfacadeクラスを変更してコントローラクラスメソッドを呼び出す
ps:私はJTAを使用しています
これにより、私は別の問題に直面しました。生成されたすべてのコントローラークラスには、独自のgetEntityManager()メソッドがあります。したがって、この冗長性を取り除くために、Hibernateチュートリアル(sessionfactoryのシングルトンとして機能する)で一般的に見られるHibernateUtil.javaのラインに沿ってヘルパークラスを使用することにしました。そこで、Controllerクラスで使用されるEntityManagerとUserTransactionのインスタンスを返すことになっているgetEntityManager()メソッドとgetUserTransaction()メソッドを持つPersistenceUtil.javaを作成しました。
問題はそこにあります。XXXFacadeクラスで@PersistenceContext((name = "jpa / EntityManager"))と@Resource(name = "jta / UserTransaction")を使用しているので、両方のXXXFacadeクラスからemとutxのJNDIエントリにアクセスできます(必要な場合は、私の場合はそうではありません)、およびXXXJpaControllerヘルパークラス(jndiルックアップを介して)で。オンラインで読んだ後、それが私が見つけたものです。ヘルパークラスは、Beanのコンポーネント環境でJNDIルックアップを使用する必要があります( java:comp / env)は、コンテナー管理対象Beanに対してのみ実行され、管理対象外のヘルパークラスに対しては実行されないためです。これは、上記のコードに示すように、XXXFacadeクラスでインスタンス化されるControllerクラスに対しては正常に機能します。ヘルパーのヘルパークラスを推測しているため、PersistenceUtilクラスを使用してEntityManagerまたはUserTransactionのいずれかを検索することはできません。これを回避し、PersistenceUtilヘルパークラスのコンテナー管理エンティティマネージャーとusertransactionにアクセスするにはどうすればよいですか?私の頭に浮かぶオプションの1つは、各XXXFacadeクラスのPersistenceクラスもインスタンス化することです(その音は好きではありません)。
私が考えることができる他の唯一のオプションは、Controllerクラスを取り除き、そのすべてのコードをXXXFacadeクラスに移動することです。そうすれば、PersistenceUtilヘルパークラスをセッションBeanに直接注入できるので、もう必要ありませんよね?
冒頭で述べたように、私は初心者です。この問題に関するガイダンスについて、経験豊富で経験豊富なjava/jeeのベテランの皆様からのご意見をお待ちしております。ここで採用できる特定のパターンはありますか?
これのどれかがあなたに意味をなさないならば、すみません。お気軽にご不明な点がございましたら、お気軽にお問い合わせください。喜んで対応させていただきます。