1

私は基本的に、新しい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のベテランの皆様からのご意見をお待ちしております。ここで採用できる特定のパターンはありますか?

これのどれかがあなたに意味をなさないならば、すみません。お気軽にご不明な点がございましたら、お気軽にお問い合わせください。喜んで対応させていただきます。

4

2 に答える 2

1

調査したいことの1つは、ファクトリメソッドを使用するのではなく、トランザクションを管理するためのSpringです。

ここにはたくさんのアドバイスがありますが、Stack Overflowだけでなくインターネット全般でも、質問が消化しやすいほど良い答えが得られることがわかりました。多くの新しいテクノロジーに直面して明確な質問を作成するのは難しい場合があることを理解しています。私自身の質問履歴にはいくつかの巨大な質問がありますが、重要なことは、誰かに助けを求める前に、あなたの考えや問題を明確にすることです。1つの質問を明確に尋ねることに焦点を当てて、これをいくつかの質問に分割する作業を行うことをお勧めします。一般的に、事前に時間をかけて明確な質問をすると、人々があなたを助けやすくなります。

于 2009-04-29T15:14:35.173 に答える
0

ええ..あなたは絶対に正しいです。質問形式についてお詫び申し上げます。それは実際にstackoverflowに関する私の最初の投稿であり、したがって質問の醜さです。とにかく、あなたのフィードバックのおかげで、私はより良い質問を投稿しようとしました。

とにかく、私は私の質問に対する答えを見つけました。コントローラクラスを使用せず、エンティティのセッションファサードBeanを使用することにしました。そして、コンテナ管理の永続性を使用しました。したがって、getEntityManager()メソッドやヘルパークラスはもう必要ありません。代わりに、「@PersistenceContext」の形式のDIを使用してください。また、コンテナ管理の永続性を使用しているので、UserTransactionsはもう必要ありません。

于 2009-08-21T14:14:20.637 に答える