web-dev-qa-db-ja.com

.earファイルのコンポーネント間で永続性ユニットを共有する

Java .earパッケージを使用しているEE 6アプリケーションで、異なる.jarファイルのコンポーネントからアクセスできる永続ユニットを作成したいと思います。

ただし、この永続性ユニットの定義方法はわかりません。 @PersistenceContextアノテーションを使用すると、名前がローカルのpersistence.xmlファイルで定義された永続性ユニットと一致する場合にのみ、検索が成功します。

外部永続性ユニットを参照することは可能ですか?

34
bamoida2010

JPA 2.0仕様の関連セクションは次のとおりです。

8.2永続性ユニットのパッケージ化

...

持続性ユニットは、persistence.xmlファイルによって定義されます。 META-INFディレクトリにpersistence.xmlファイルが含まれているjarファイルまたはディレクトリは、永続性ユニットのルートと呼ばれます。 Java EE環境では、永続性ユニットのルートは次のいずれかである必要があります。

  • eJB-JARファイル
  • wARファイルのWEB-INF/classesディレクトリ[80]
  • wARファイルのWEB-INF/libディレクトリにあるjarファイル
  • eARライブラリディレクトリのjarファイル
  • アプリケーションクライアントのjarファイル

持続性ユニットにEJB-JARまたはWARに含まれるクラスに加えて持続性クラスが含まれていない限り、持続性ユニットを含むEJB-JARまたはWARファイルをEARにパッケージ化する必要はありません。セクション8.2.1.6を参照してください。

注:Java Persistence 1.0は、EARのルートにあるjarファイルの永続性ユニットのルートとしての使用をサポートしています。この使用はサポートされなくなりました。ポータブルアプリケーションは、この場合、代わりにEARライブラリディレクトリを使用する必要があります。[9]を参照してください。

永続性ユニットには名前が必要です。単一のEJB-JARファイル内、単一のWARファイル内、単一のアプリケーションクライアントjarファイル内、またはEAR内では、特定の名前の永続性ユニットを1つだけ定義する必要があります。セクション8.2.2「持続性ユニットのスコープ」を参照してください。

persistence.xmlファイルは、同じスコープ内の複数の永続性ユニットを指定するために使用できます。

Java EE EARのレベルで定義されたすべての永続クラスは、他のすべてのJava EEコンポーネントにアクセスできる必要があります。 application-つまり、アプリケーションクラスローダーによってロードされます-同じエンティティクラスが2つの異なるJava EEコンポーネント(異なる永続性ユニットを使用している可能性がある)によって参照される場合) )、参照されるクラスは同じ同一のクラスです。

以降:

8.2.2永続性ユニットのスコープ

EJB-JAR、WAR、アプリケーションクライアントjar、またはEARは永続性ユニットを定義できます。

unitNameアノテーション要素またはpersistence-unit-nameデプロイメント記述子要素を使用して永続性ユニットを参照する場合、永続性ユニットの可視性スコープは、その定義ポイントによって決定されます。

  • EJB-JAR、WAR、またはアプリケーションクライアントjarのレベルで定義された永続性ユニットは、それぞれそのEJB-JAR、WAR、またはアプリケーションjarをスコープとし、そのjarまたはwarで定義されたコンポーネントに表示されます。
  • EARのレベルで定義された永続性ユニットは、通常、アプリケーション内のすべてのコンポーネントに表示されます。ただし、同じ名前の永続性ユニットが、EJB-JAR、WAR、またはEAR内のアプリケーションjarファイルによって定義されている場合、EARレベルで定義されたその名前の永続性ユニットは、持続性ユニットの参照が持続性ユニット名#構文を使用してパス名を指定し、参照を明確にする場合を除き、そのEJB-JAR、WAR、またはアプリケーションjarファイルによって定義されたコンポーネントに表示されます。#構文を使用する場合、パス名は、参照するアプリケーションコンポーネントのjarファイルからの相対パスです。たとえば、構文../lib/persistenceUnitRoot.jar#myPersistenceUnitは、persistence.xmlファイルのname要素で指定された名前がmyPersistenceUnitであり、ルートの相対パス名を持つ永続性ユニットを参照します永続化ユニットの../lib/persistenceUnitRoot.jarです。 #構文は、unitNameアノテーション要素またはpersistence-unit-nameデプロイメント記述子要素の両方で使用して、EARレベルで定義された永続性ユニットを参照できます。

また、puクラスのマニフェストにエンティティクラスjarを含める必要があります http://wiki.Eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

要約すると、EARの最上位レベルでエンティティーと永続性ユニットを定義し、それらを他のモジュールから使用できるようにする必要があります。

あなたが何を試み、どのような問題に直面したのか、私にはわかりません。

47
Pascal Thivent

この問題は、persistence.xmlを、earのlibディレクトリにあるjarファイルに配置することで解決できます。

Persistence.xmlには、エンティティを含むjarファイルが含まれている必要があります。 jarファイルへの相対パスを指定する必要がありました。私の耳の直腸構造

|-ear--
       |-lib--|... some libs ...
       |      |--my-persistence-xml.jar
       |-ejb-with-entities1.jar
       |-ejb-with-entities2.jar

Jboss 7.1.1のpersistence.xml

<persistence-unit name="my-pu" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>Java:jboss/datasources/mypu</jta-data-source>
    <jar-file>../ejb-with-entities1.jar</jar-file>
    <jar-file>../ejb-with-entities1.jar</jar-file>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true" />
    </properties>
 </persistence-unit>

お役に立てれば

14
christian

必要なものすべて

EAR +
    |- META-INF +
    |       - persistence.xml
    |- ejb1-module.jar
    |- ejb2-module.jar


<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://Java.Sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="my-persistence-unit">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>MyDataSource</jta-data-source>
        <!-- Note: it's relative to `persistence-module.jar` file location in EAR -->
        <jar-file>../ejb1-module.jar</jar-file>
        <jar-file>../ejb2-module.jar</jar-file>
        <properties>
            ...

        </properties>
    </persistence-unit>
</persistence>
9
jprism

GlassfishのEARレイアウトの例:

EAR +
    |- lib +
    |      |- core-module.jar
    |      \- persistence-module.jar +
    |                                 \- META-INF +
    |                                              \- persistence.xml
    |- ejb1-module.jar
    \- ejb2-module.jar

EJBモジュールは、jarアーカイブまたは展開ディレクトリのいずれかです。

この場合、persistence.xmlは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://Java.Sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="my-persistence-unit">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>MyDataSource</jta-data-source>
        <!-- Note: it's relative to `persistence-module.jar` file location in EAR -->
        <jar-file>../ejb1-module.jar</jar-file>
        <jar-file>../ejb2-module.jar</jar-file>
        <properties>
            <property name="hibernate.current_session_context_class" value="jta"/>
            <property name="hibernate.id.new_generator_mappings" value="true"/>
            <property name="hibernate.dialect"      value="org.hibernate.dialect.PostgreSQL82Dialect"/>
            <property name="hibernate.show_sql"     value="true"/>
            <property name="hibernate.format_sql"   value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

モジュールのバージョン管理を使用する場合は、<jar-file>参照を更新する必要があります(例:ejb1-module-1.0-SNAPSHOT.jar)。

@MappedSuperclassアノテーションとEntityManagerインジェクションを持つ抽象オブジェクトは、任意の外部jarに配置できます。このjarはpersistence.xmlで言及する必要はありません。たとえば、core-module.jarPersistableEntity.Javaで作成できます。

public class PersistableEntity {
    @Id
    @GeneratedValue
    private Long id;

    public Long getId() { return id; }

    public Integer getVersion() { return version; }
}

そしてPersistableEntityManager.Java

public class PersistableEntityManager<T extends PersistableEntity> {
    @PersistenceContext
    protected EntityManager em;
}

このcore-module.jarは、異なる永続性ユニットを持つすべてのプロジェクトで使用できます。エンティティとEJBを継承するだけで、ボイラープレートを回避できます。例 githubのbilionix-core を確認してください。

これで試してください:

  1. この方法でEAR application.xmlファイルを構成します。

    http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd "version =" 7 "> YourEEApplication

    <initialize-in-order>true</initialize-in-order> <!-- This is the most important thing -->
    
    <module>
        <ejb>YourEJBModule1.jar</ejb>
    </module>
    <module>
        <ejb>YourEJBModule2.jar</ejb>
    </module>
    ......
    <module>
        <ejb>YourEJBModuleX.jar</ejb>
    </module>
    
    <module>
        <web>
            <web-uri>YourWebModule.war</web-uri>
            <context-root>YourWebModule</context-root>
        </web>
    </module>
    
  2. EJBプロジェクトで、YourEJBModule1、YourEJBModule2 ...、およびYourEJBModuleX:

UnitNameプロパティを使用して永続コンテキストを挿入します。

@PersistenceContext(type=PersistenceContextType.TRANSACTION)
    private EntityManager em; // get & set
  1. 各EJBモジュールのpersistence.xmlファイルについて:

YourEJBModule1:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="PersistenceUnit1"
        transaction-type="JTA">
        <provider>org.Eclipse.persistence.jpa.PersistenceProvider</provider>

        <jta-data-source>jdbc/YourDataSource</jta-data-source>
        <class>com.example.Foo1</class>
        <!-- Other properties -->
    </persistence-unit>
</persistence>

YourEJBModule2:

<?xml version="1.0" encoding="UTF-8"?>
...
    <persistence-unit name="PersistenceUnit2"
        transaction-type="JTA">
        <provider>org.Eclipse.persistence.jpa.PersistenceProvider</provider>

        <jta-data-source>jdbc/YourDataSource</jta-data-source>
        <jar-file>YourEJBModule1.jar</jar-file>
        <class>com.example.Foo2</class>
        <!-- Other properties -->
    </persistence-unit>
...

YourEJBModuleX:

<?xml version="1.0" encoding="UTF-8"?>
...
    <persistence-unit name="PersistenceUnitX"
        transaction-type="JTA">
        <provider>org.Eclipse.persistence.jpa.PersistenceProvider</provider>

        <jta-data-source>jdbc/YourDataSource</jta-data-source>
        <jar-file>YourEJBModule1.jar</jar-file>
        <jar-file>YourEJBModule2.jar</jar-file>
        ......
        <class>com.example.FooX</class>
        <!-- Other properties -->
    </persistence-unit>
...

データベースには、EJBモジュールごとに1つ、さまざまなスキーマが存在し、jta-data-sourceを介してそれらにアクセスできます。

(Glassfish 4にデプロイ)

1
Juan Rodriguez