Glassfish v3 サーバーを使用しています。
通常、EJB3 + JPA (Eclipselink) との DB 接続は、@PersistenceUnit または @Persistencecontext を使用したインジェクションによって行われます。
ただし、私のアプリには3つのレイヤーがあります:
コア (ビジネス ロジック、エンティティ、例外処理などを含む)
その上に EJB を配置し、適切なコア オブジェクトとメソッドを呼び出してジョブを実行します。この EJB は、ERP の他の内部モジュールによって呼び出されます。
フロントエンド Web サイトで使用するための REST レイヤー。
EJB で entityManager も EMF (EM ファクトリ) も取得したくありません。これは、中間層がその下で使用される DB があることを認識しないようにするためです。結局、後で、コアの実装を DB を使用しない実装に変更することを決定できます。
私は2つの悪い解決策しか見ていません:
1) DB 接続が必要なコア層のメソッドを呼び出すたびに EM パラメータを追加します。非常に醜く、私が上で言ったことに反します。
2) DB 接続を必要とするコアのすべてのメソッドで、ファクトリ、EM を作成し、それらを使用してから、両方を閉じます。
Core レベルのクラスごとに 1 つのファクトリを持ち、すべてのメソッドで EM が作成され、閉じられます。しかし、私はまだこのようなメモリリークがあります:
javax.servlet.ServletException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.0.v20091127-r5931): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.
私の EJB メソッドの 1 つが 10 個の異なるオブジェクトを使用すると、10 個の EM ファクトリが作成され、どれも閉じられていないためだと思います。
Core オブジェクトでの一般的な使用例:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// do some stuff with em; for example persist, etc
em.flush();
em.close();
解決策 2 を使用する必要がありますか? このコア レベルで単一の EM ファクトリを使用する方法はありますか? JPA 仕様では、EJB レベルでのみエンティティを使用することを想定しているようですが、これは多層アプリでは不適切です。
編集: @Inject を試した後の現在のステータスは次のとおりです。
CORE jar の /META-INF ディレクトリに空の beans.xml ファイルを追加しました。
親DAOクラスは次のようになりました:
public class ExampleBZL {
public EntityManagerFactory emf; @Inject public Emf emfobject; public ExampleBZL() { this.emf = emfobject.emf; }
Emf クラスは非常に単純で、ステートレスです。
@Stateless public class Emf は EmfAbstract を実装します {
@PersistenceUnit(unitName = Setup.persistenceUnitName) public EntityManagerFactory emf; public Emf() { }
}
私は何か間違ったことをしているに違いありませんが、グラスフィッシュではエンジンリストに「[ejb、weld、web]」が表示されているため、CDIがロードされていますが、インジェクションは機能しません。
Servlet.service() for servlet Jersey Web Application threw exception
java.lang.NullPointerException
at com.blablabla.core.bizlogic.ExampleBZL.<init>(ExampleBZL.java:40)
他の注釈がありませんか?? これら 2 つの小さな注釈 (一方はステートレス、もう一方は注入) を使用して JAR で inect を実行することは本当に機能していますか?