Отсоединить JAR-файл сущности от файла persistence.xml в среде SE - PullRequest
13 голосов
/ 12 апреля 2010

Есть ли способ повторно использовать банку с аннотированными сущностями JPA в более чем одном приложении SE (как зависимость)? в файле persistence.xml не поддерживается в средах SE, поэтому есть ли другой способ?

Ответы [ 4 ]

6 голосов
/ 12 апреля 2010

Официально (согласно спецификации), вы должны указать все классы, используя элемент class . Цитирование главы 6.2.1.6 mapping-file, jar-file, class, exclude-unlisted-classes из JSR-220 :

Список именованных управляемых классов персистентности также может быть указан вместо файлов JAR и файлов сопоставления или в дополнение к ним. Любые аннотации метаданных сопоставления, найденные в этих классах, будут обработаны, или они будут сопоставлены с использованием значений аннотаций сопоставления по умолчанию. Элемент class используется для вывода списка управляемого класса сохраняемости. Список всех именованных классов управляемой персистентности должен быть указан в средах Java SE для обеспечения переносимости . Портативные приложения Java SE не должны полагаться на другие механизмы, описанные здесь, для указания управляемых классов персистентности модуля персистентности. Поставщики постоянства могут также потребовать, чтобы набор классов сущностей и классов, которыми нужно управлять, должен быть полностью перечислен в каждом из файлов persistence.xml в средах Java SE.

Теперь, если вы не против переносимости, Hibernate поддерживает , используя элемент jar-file в Java SE (в этом случае нужен абсолютный URL, а не удобный). Hibernate также поддерживает автоопределение даже в JSE. Гораздо лучше:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  version="1.0">
  <persistence-unit name="foo">

    <!-- This is required to be spec compliant, Hibernate however supports auto-detection even in JSE. -->
    <class>foo.Bar<class>

    <properties>
      <!-- Scan for annotated classes and Hibernate mapping XML files -->
      <property name="hibernate.archive.autodetection" value="class, hbm"/>
      ...
    </properties>
  </persistence-unit>

</persistence>
2 голосов
/ 06 октября 2011

Из моего опыта - теперь работает.

Мы используем: Hibernate3.jar 3.6.0.Final Зимуют-JPA-2,0-апи-1.0.0.Final.jar

Файл : ... </ jar-file> знает, как искать относительные пути, и работает как для jar-файлов, так и для каталогов.

Я использую эту способность дважды:

  • с банкой, в которой хранятся мои сущности - которая используется в нескольких приложениях. Каждое приложение имеет свой собственный файл persistence.xml - главным образом для предоставления различных настроек ehcache.
  • С Junits, когда я хочу, чтобы все мои тесты во всех других зависимых проектах имели один файл persistence.xml, который будет указывать на все сущности в проекте сущностей. Затем мы сохраняем файл persistence.xml в проекте лица в каталоге test / resources / META-INF, указывая на каталог Bin этого проекта: файл: ../ entity / bin </ jar-file>
2 голосов
/ 12 апреля 2010

Насколько я знаю, нет способа заставить класс сканировать аннотации для работы в этой конфигурации. Однако вы можете явно указать свой файл persistence.xml на каждый класс сущностей.

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
                     version="1.0">

  <persistence-unit name="punit">

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <jta-data-source>java:/myDS</jta-data-source>

    <!-- Must be explicit as classes are in separate jar -->
    <class>com.foo.Bar</class>
    <class>com.foo.Baz</class>

    <properties/>      
  </persistence-unit>

</persistence>
1 голос
/ 02 февраля 2011

Это была проблема, с которой я столкнулся. Чуть более неприятно, так как мне нужно запустить несколько кувшинов, а также часть военного развертывания.

Есть несколько хаков, которые, кажется, вращаются вокруг нескольких файлов persistence.xml и / или какой-то странной попытки попытаться сослаться на файл jar с помощью весенних загрузчиков ресурсов (которые у меня не работали).

Мой личный прием - использовать загрузчики ресурсов Spring для разрешения ресурса, находящегося во ВСЕХ jar-объектах, анализировать ссылку на jar-адрес URL-адреса и использовать диспетчер модулей Spring Persistence для внедрения их в тег jar-file в виртуальном постоянном хранилище .xml

Это обходной способ, но избегается многократное использование persistence.xml, что технически недопустимо.

public class SpringPersistenceUnitManager extends DefaultPersistenceUnitManager implements ApplicationContextAware {

private final Logger log = LoggerFactory.getLogger(getClass());

private ApplicationContext ctx = null;


private String jarLocationPattern;

@Override
protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
    super.postProcessPersistenceUnitInfo(pui);
    try {
        Resource[] resources = ctx.getResources("classpath*:applicationContext.xml");
        for (Resource res : resources) {
            String resJar = resolveJar(res.getURL());
            if (!resJar.equals(pui.getPersistenceUnitRootUrl().toString())) {
                log.info("Adding " + resJar + " to persistence context");
                pui.addJarFileUrl(new URL(resJar));
            }
        }
    }
    catch (IOException e) {
        log.error("error", e);
    }
}

private String resolveJar(URL fileInJar) {
    String path = fileInJar.getPath();
    return path.substring(0, path.indexOf('!'));
}

и контекстные материалы весны:

<util:properties id="hibernate.properties" location="classpath:hibernate.properties" />

<bean id="persistenceUnitManager" class="com.rokksoft.blackice.util.SpringPersistenceUnitManager"
    p:defaultDataSource-ref="jdbcDataSourcePool"
/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true"
    p:persistenceUnitManager-ref="persistenceUnitManager"
    p:persistenceUnitName="blackicePU"
    p:dataSource-ref="jdbcDataSourcePool"
    p:jpaProperties-ref="hibernate.properties">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
</bean>

Вы хотите отфильтровать имена банок в идеале - в банке стороннего производителя может быть что угодно.

...