0

私は Apache Felix で ServiceMix を使用しており、エンタープライズ アプリケーションは複数のバンドルで構成されています。たとえば、jpa エンティティ クラスを含むバンドルと、ビジネス ロジックと dao クラスを含む別のバンドルがあります。私は OpenJPA を使用しているため、entity-bundle プロジェクトはコンパイル時にバイトコードを挿入するために META-INF フォルダーに persistenc.xml が必要ですが、このバンドルはバンドル マニフェストの Meta-Persistence ヘッダーによって永続化ユニットを提供します。dao 提供バンドル内に、blueprint.xml を使用してエンティティ マネージャーを挿入します。

<bean id="systemUserDAOBean" class="server.daos.SystemUserDAO">
  <tx:transaction method="*" value="Required" /> 
  <jpa:context property="entityManager" unitname="mypu" />
</bean>

実行時にdaoの次のメソッドを呼び出すと:

public SystemUser readSystemUser(String username) {
        final EntityManager em = getEntityManager();
        final Query q = em.createQuery("select a from SystemUser a where a.username = '"+username+"'");
        return (SystemUser) q.getSingleResult();
}

ClassCastException がスローされます。

java.lang.ClassCastException: mypackage.SystemUser を mypackage.SystemUser にキャストできません

私が今までに見つけたのは、オブジェクトを返すエンティティマネージャーのクラスをロードしたクラスローダーは、メソッドの戻り型をロードしたクラスローダーとは異なるということです。たぶん、最初のクラスローダはエンティティバンドルのクラスローダで、2 番目はバンドルを提供する dao のクラスローダですか?!

persistence.xml を DAO-Bundle にコピーし、blueprint.xml で永続化ユニットを使用すると、ClassCastException はスローされません。しかし、この場合、同じアプリケーション内にまったく同じpersistence.xmlファイルが2つあります。これは望ましくありません。:(

誰もその問題を解決する方法を知っていますか?

ありがとう、フィル

編集: servicemix を再起動すると、永続化バンドルを更新するまで例外がなくなります。そして、両方のクラスローダーが永続性バンドルに由来することがわかりました。

4

1 に答える 1

0

ドメイン クラス (を含むSystemUser) を複数のバンドルにコピーしたようです。発見したように、Java は異なる ClassLoader によってロードされた同じクラスを異なるクラスと見なし、したがってClassCastException.

Export-Packageヘッダーを使用して、1 つのバンドルからドメイン パッケージをエクスポートする必要があります。おそらく、これは永続バンドルから行う必要があります。他のすべてのバンドルは、そのパッケージをインポートする必要があります。

于 2013-11-14T20:02:07.027 に答える