Ответ 1
Ниже приведены классы Hibernate JPA 2 (javax.persistence...):
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
Я пытаюсь создать модуль агностической реализации maven, который опирается на JPA2. К сожалению, единственная зависимость от Maven JPA основана на JPA1, и поэтому я не могу использовать метод EntityManager.detach(), поскольку это только вариант JPA2.
В идеале, мне бы хотелось указать мою зависимость javax.persistence в моем Pom и потребовать, чтобы приложение/контейнер поставляли реализацию JPA2. К сожалению, я не могу найти такую зависимость.
Является ли мой единственный выбор в этой точке объявлять hibernate-jpa-2.0-api 1.0.0.FINAL как предоставленную зависимость?
Ниже приведены классы Hibernate JPA 2 (javax.persistence...):
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
Я знаю, что это довольно старое сообщение, если вы хотите пойти вне агностики от реализации, тогда вместо этого вы должны использовать зависимость API Java EE.
Просто добавьте в свой POM:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${jee.version}</version>
<scope>provided</scope>
</dependency>
Где ${jee.version} - ваша желаемая версия Java EE. В настоящее время я использую 7.0. Он имеет все зависимости EJB, JPA и JSF API.
Я использую артефакт javax.persistence
(а не артефакт eclipselink
) из репозитория EclipseLink Maven для доступа к классам API JPA 2. Фрагменты из POM включают:
<project>
...
<dependencies>
...
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
<repositories>
...
<repository>
<id>EclipseLink Repo</id>
<!-- note that ampersands in this URL are escaped because this is in an
xml file - un-escape them to use in browser -->
<url>http://www.eclipse.org/downloads/download.php?r=1&nf=1&file=/rt/eclipselink/maven.repo</url>
</repository>
...
</repositories>
...
</project>
Артефакт javax.persistence
содержит все классы API, и ни один из классов EclipseLink (кроме двух) не позволяет указать область действия; это применимо даже для провайдера JPG EclipseLink (который находится в идентификаторе артефакта eclipselink
).
Я не смешивал артефакт javax.persistence
с артефактом hibernate-entitymanager
, так как я управлял зависимостью для другого проекта, который полагается на Hibernate EntityManager вместо EclipseLink для поставщика JPA. Ниже показан фрагмент из второго проекта POM:
<project>
<dependencies>
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.5.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
</project>
Я изменяю области зависимостей от provided
до test
в других проектах, чтобы гарантировать, что модульные тесты будут иметь поставщика JPA в пути к классам. Это в первую очередь делается для маскировки побочных эффектов использования зависимости javaee-api
, которую я использую в родительском POM, чтобы разрешить компиляцию ссылок на несколько Java EE 6 API-классы.
Это наиболее релевантный и официальный API для JPA2 от EclipseLink:
<repositories>
<repository>
<url>http://download.eclipse.org/rt/eclipselink/maven.repo/</url>
<id>eclipselink</id>
<layout>default</layout>
<name>Repository for library EclipseLink (JPA 2.0)</name>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
В отличие от Hibernates API, это официальная спецификация и поддержка лучших дженериков, когда дело доходит до использования API критериев.
Для API JPA 2.2 "официальный" артефакт доступен из центра maven, см. этот ответ.
На сегодняшний день я считаю, что наиболее актуальным является следующее:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
Вот как вы можете использовать JPA в maven:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.10.Final</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.2_spec</artifactId>
</exclusion>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Мне удалось решить проблему с моей зависимостью от Maven JPA2, добавив пару зависимостей в файл проекта pom.xml. Ниже приведен код xml для зависимостей.
Я нашел последние версии groupId и artifactId, сверяя каталоги на Maven Central. Я просто прошел дерево каталогов, пока не нашел файлы metadata.xml для persistence.core и persistence.jpa артефакты.
Примечание: зависимость от persistence.jpa - это то, что на самом деле приносит javax.persistence jar.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>2.6.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.4</version>
<scope>compile</scope>
</dependency>