Совместное использование модуля персистентности между компонентами в файле .ear - PullRequest
33 голосов
/ 02 ноября 2010

В приложении Java EE 6, в котором я использую упаковку .ear, я хотел бы создать модуль персистентности, к которому можно обращаться из компонентов в различных файлах .jar.

Однако яне уверен, как определить эту единицу постоянства.С аннотацией @PersistenceContext поиск выполняется только в том случае, если имя соответствует единице постоянства, определенной в локальном файле persistence.xml.

Можно ли ссылаться на внешние единицы постоянства?

Ответы [ 7 ]

47 голосов
/ 02 ноября 2010

Вот соответствующие разделы спецификации JPA 2.0:

8.2 Упаковка единицы измерения постоянства

...

Единица сохранения состояния определяется persistence.xml файл.Файл или каталог jar, каталог которого META-INF содержит файл persistence.xml, называется корнем единицы сохраняемости.В средах Java EE корень постоянного модуля должен быть одним из следующих:

  • файл EJB-JAR
  • WEB-INF / classesкаталог файла WAR [80]
  • файл JAR в каталоге WEB-INF / lib файла WAR
  • файл JAR в каталоге библиотеки EAR
  • файл JAR клиента приложения

Не требуется, чтобы файл EJB-JAR или WAR, содержащий единицу постоянства, был упакован в EAR, если только модуль персистентности не содержит классов постоянства в дополнение кте, которые содержатся в EJB-JAR или WAR.См. Раздел 8.2.1.6.

ПРИМЕЧАНИЕ. Java Persistence 1.0 поддерживает использование файла JAR в корне EAR в качестве корня единицы сохраняемости.Это использование больше не поддерживается. В этом случае переносные приложения должны использовать каталог библиотеки EAR .См. [9].

Персистирующая единица должна иметь имя.В одном файле EJB-JAR, в одном файле WAR, в одном клиентском jar-приложении или в EAR-файле должна быть определена только одна единица сохранения любого заданного имени.См. Раздел 8.2.2, «Область действия единиц сохраняемости».

Файл persistence.xml может использоваться для обозначения нескольких единиц постоянства в одной и той же области действия.

Все классы устойчивостиопределенный на уровне Java EE EAR должен быть доступен для всех других компонентов Java EE в приложении - то есть загружен загрузчиком классов приложения - таким образом, если на один и тот же класс сущности ссылаются два разных компонента Java EE (используя разные единицы персистентности), указанный класс - это тот же идентичный класс.

и более поздние версии:

8.2.2 Область единиц персистентности

AnEJB-JAR, WAR, JAR-файл приложения или EAR могут определять единицу сохраняемости.

При ссылке на единицу постоянства с помощью элемента аннотации unitName или элемента дескриптора развертывания persistence-unit-name область видимости постоянстваЕдиница измерения определяется точкой определения:

  • Единица постоянства, определяемая на уровне EJB-JAR, WAR или jar приложения-клиента привязываются к этому EJB-JAR, WAR или jar приложения соответственно и видны компонентам, определенным в этом jar или war.
  • Единица персистентности, котораяопределяется на уровне EAR, как правило, видимым для всех компонентов в приложении .Однако , если единица персистентности с тем же именем определена файлом EJB-JAR, WAR или jar приложения в EAR, единица персистентности с таким именем, определенная на уровне EAR, не будет видна компонентам, определеннымэтот файл EJB-JAR, WAR или jar приложения, если только ссылка на постоянную единицу не использует синтаксис имени постоянной единицы #, чтобы указать путь для устранения неоднозначности ссылки. При использовании синтаксиса # имя путиотносится к файлу JAR, на который ссылается компонент приложения.Например, синтаксис ../lib/persistenceUnitRoot.jar#myPersistenceUnit относится к единице сохраняемости, имя которой, как указано в элементе имени файла persistence.xml, равно myPersistenceUnit и для которой относительный путь к корню единицы постоянства равен ../lib/persistenceUnitRoot.jar.Синтаксис # может использоваться как с элементом аннотации unitName, так и с элементом дескриптора развертывания persistence-unit-name для ссылки на единицу сохраняемости, определенную на уровне EAR.

Также необходимо включить классы сущностей jarв манифесте пу банку http://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

Подводя итог, вы должны иметь возможность определять свои сущности и единицу персистентности на верхнем уровне EAR и использовать их из других модулей.

Я просто не уверен, что понимаю, что вы пытались и с какими проблемами вы столкнулись.

13 голосов
/ 05 июля 2012

Эту проблему можно решить, поместив файл persistence.xml в файл jar, расположенный в каталоге lib уха.

Файл persistence.xml должен содержать файлы jar, в которые входят сущности. Мне пришлось указать относительный путь к файлам jar. Структура моего уха irectory

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

Мой файл persistence.xml для jboss 7.1.1

<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>

Надеюсь, это поможет

8 голосов
/ 23 ноября 2014

Все, что вам нужно

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>
5 голосов
/ 20 февраля 2013

Пример рабочего макета EAR для Glassfish:

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 могут быть помещены в любую внешнюю банку. Этот сосуд не требуется указывать в persistence.xml. Например, вы можете создать core-module.jar с помощью PersistableEntity.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 и избегаете шаблонов. Посмотрите пример bilionix-core на github .

1 голос
/ 03 декабря 2015

Попробуйте это:

  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
Для каждого файла persistence.xml модуля EJB:

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, доступ к ним через jta-data-source

(развернут в Glassfish 4)

0 голосов
/ 22 ноября 2013

Я хотел получить модуль EJB с общим постоянством без проекта EAR.

Это возможно, если

  1. переместить все персистентные сущности в отдельный проект EJB (не перемещайте persistance.xml в новый проект, нужны только классы
  2. при компиляцииEJB project
  3. отправка проекта на сервер GlassFish с использованием
scpAsSudo ~/NetbeansProjects/UnifyEntities/dist/UnifyEntities.jar remoteUsername@192.168.0.1:/opt/glassfish3/domains/domain1/lib/ext

Веселитесь!

0 голосов
/ 02 ноября 2010

Вот что я сделал.

1) Упакуйте файлы конфигурации постоянства в файл jar.Файл jar будет содержать:

  • META-INF / persistence.xml (и orm.xml, если вы его используете)
  • Создать папку "lib" в EARспроектируйте и вставьте туда jar

2) Упакуйте связанные классы сущностей в другой jar:

  • Поместите этот файл jar в вашу папку GlassFish / lib.(или любой другой эквивалентной папки lib на других серверах)
  • Я изначально связал jar в папке lib библиотеки EAR, но классы не были найдены
  • Если кто-либознает, как лучше справиться с этим, объясните, пожалуйста,

Контекст Persistence теперь должен быть доступен для всех EJB и веб-приложений, входящих в ваше корпоративное приложение.

...