Развяжите банку объектов JPA от persistence.xml в среде SE
Есть ли способ повторно использовать банку с аннотированными объектами JPA в более чем одном приложении SE (как зависимость)? < банка файл > в persistence.xml не поддерживается в средах SE, так есть ли другой способ?
Ответы
Ответ 1
Официально (для каждой спецификации) вам нужно указать все классы, используя элемент class
. Цитируя раздел 6.2.1.6 map-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
Насколько я знаю, нет способа заставить сканирование классов для аннотаций работать в этой конфигурации. Однако вы можете явно указать свой файл 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>
Ответ 3
Из моего опыта - теперь он работает.
Мы используем:
Hibernate3.jar 3.6.0.Final
спящий режим JPA-2,0-апи-1.0.0.Final.jar-
jar-file > file:... </jar-file > умеет искать относительные пути - и он работает как для файлов jar, так и для каталогов.
Я использую эту способность дважды:
- с Jar, в котором хранятся мои объекты, - который используется в нескольких приложениях. каждое приложение имеет свой собственный persistence.xml - в основном для обеспечения разных настроек ehcache.
- С Junits, когда я хочу, чтобы все мои тесты во всех других зависимых проектах имели один файл persistence.xml, который будет указывать на все сущности в проекте сущностей. Затем мы сохраняем persistence.xml в проекте сущностей под тестом /resources/META -INF, указывающим на каталог Bin этого проекта:
< jar-file > file:../entity/bin </jar-file >
Ответ 4
Это была проблема, с которой я столкнулся. Немного более преувеличен, так как мне нужно запустить несколько банок отдельно, а также часть военного развертывания.
Есть несколько хаков, которые, кажется, вращаются вокруг нескольких файлов persistence.xml и/или какой-то странно выглядящей попытки попытаться ссылаться на файл jar с помощью spring загрузчиков ресурсов (что не работает для меня).
Мой персональный взлом - использовать загрузчики ресурсов spring для разрешения ресурса, который находится во всех банках сущности, проанализировать ссылку на URL-адрес и использовать диспетчер единиц хранения spring, чтобы ввести их в тег jar файла в виртуальном persistence.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('!'));
}
и контекстный материал spring:
<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>
Вы хотите отфильтровать имена баннеров в идеале, хотя - сторонняя банка может иметь что угодно.