У меня есть Java-проект, который использует JPA 2.0 с Hibernate 4.3.4. Все нормально, когда я запускаю его внутри Eclipse. Но когда я позволяю Eclipse экспортировать runnable JAR, проблема начинается, и программа вылетает из-за, казалось бы, отсутствующей единицы непрерывности...
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyDBManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
... или, казалось бы, неотображаемые классы...
3024 Thread-4| FATAL DbManager : DBManager could not load countries from database.
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Country is not mapped [SELECT x FROM Country x]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331)
,
В зависимости от вида экспорта (извлечение против упаковки или копирование библиотек) я сталкиваюсь с различными ошибками, которые противостоят решению. Самое большее, что я получаю, - это последний подход, который также я должен выбрать по причинам лицензии, поэтому позвольте сосредоточиться на этом.
В этом случае экспортируемый JAR не просматривает свой файл persistence.xml. Я уточню, что позже, но сначала некоторую справочную информацию...
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="MyDBManager" transaction-type="RESOURCE_LOCAL">
<!-- <exclude-unlisted-classes>false</exclude-unlisted-classes> -->
<!-- <class>isi.eload.core.Country</class> -->
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<!-- Do not define a connection here - this is done by the DbManager according to the command line arguments -->
<property name="hibernate.id.new_generator_mappings" value="true" />
<!-- <property name="hibernate.archive.autodetection" value="class, hbm" /> -->
</properties>
</persistence-unit>
</persistence>
Я играл с комментариями, когда я почувствовал, что xml фактически обработан (см. Ниже), но это не помогло.
По сути, из 4.3.4 Final Release:
,
Как я уже указывал ранее, экспортированный JAR не смог обработать файл persistence.xml. Когда я выполняю его в вышеуказанной структуре папок, генерируется следующее исключение:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MyDBManager
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:61)
Это исключение обычно вызывается, когда файл был найден, но имя единицы сохранения, присвоенное Persistence.createEntityManagerFactory
, не соответствует какой-либо единице сохранения, объявленной в файлах. Но это определенно не так! У меня нет хорошей идеи, почему это исключение выбрано.
Когда я редактирую банку (хотя я не уверен, что такая подделка не вызывает проблем сама по себе) и пустая или удаляющая persistence.xml, ошибка остается прежней.
Мой первый ответ заключался в том, чтобы скопировать папку meta-inf рядом с JAR:
Это, похоже, работает, так как теперь можно создать фабрику менеджера объектов. Но тогда никаких сущностей не найдено, и я думаю, что это связано с тем фактом, что используемый persistence.xml не является "на том же пути класса", что и JAR.
У кого-нибудь есть ссылка или идея, как я могу это исправить? Предпочтительно, заставляя банку использовать папку meta-inf, которая она содержит.
META-INF
должен быть в верхнем регистре. Если Java пытается получить доступ к файловой системе в Windows (или OSX в этом отношении), META-INF/persistence.xml
будет автоматически переведена в meta-inf/persistence.xml
операционной системой. Как только вы упаковываете его в JAR, он становится чувствительным к регистру и перестает работать.