Нет поставщика сохраняемости для EntityManager с именем persistence.xml

Это не дубликат, как указано выше. На этот вопрос еще не ответили.

Я пытаюсь настроить этот учебник, чтобы получить hyperjaxb работать в проекте затмения. Как я могу получить это, чтобы видеть поставщика постоянства? hbm2ddl еще не создал структуру таблицы в базе данных. Вот почему приложение не видит поставщика постоянства? Или это потому, что содержание persistence.xml в target/generated-sources не доступны из src/main/java каталог, в котором мой TestFunctions.java пытается это назвать? Вот специфика... Эта строка кода:

entityManagerFactory = Persistence.createEntityManagerFactory("persistence.xml", persistenceProperties);  

Выдает эту ошибку:

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named persistence.xml
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at maintest.TestFunctions.setUpPersistence(TestFunctions.java:119)
    at maintest.Main.main(Main.java:10)

Код, выдающий ошибку, находится в этом методе:

public void setUpPersistence(){
    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        Class<? extends TestFunctions> c = getClass();
        ClassLoader cl = c.getClassLoader();
        is = cl.getResourceAsStream("persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException i) {i.printStackTrace();}
    finally {if (is != null) {try {is.close();} catch (IOException ignored) {}}}
    entityManagerFactory = Persistence.createEntityManagerFactory("persistence.xml", persistenceProperties);
}  

persistence.xml:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <persistence-unit name="org.jvnet.hyperjaxb3.ejb.tests.po">
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.Items</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.Items$Item</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.PurchaseOrderType</class>
            <class>org.jvnet.hyperjaxb3.ejb.tests.po.USAddress</class>
        </persistence-unit>
    </persistence>

persistence.properties является:

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.username=someusername
hibernate.connection.password=somepassword
hibernate.connection.url=jdbc:mysql://localhost/somedatabasename
hibernate.hbm2ddl.auto=create-drop
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
hibernate.jdbc.batch_size=0

Структура каталогов для проекта eclipse:


**РЕДАКТИРОВАТЬ: **

Просто для удовольствия я перенес META-INF папка на том же уровне, что и вызывающий класс, но я получаю ту же ошибку. Вот два новых снимка экрана, показывающих местоположения файла persistence.xml, в котором все еще появляется ошибка:


ВТОРОЙ РЕДАКТИРОВАТЬ:

я добавил Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider"); в строке 116 TestFunctions.java, который вызывает следующую ошибку, когда я щелкаю правой кнопкой мыши на Main.java и делать Run As..Java Application:

Exception in thread "main" java.lang.ClassNotFoundException: org.eclipse.persistence.jpa.PersistenceProvider
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)
    at maintest.TestFunctions.setUpPersistence(TestFunctions.java:116)
    at maintest.Main.main(Main.java:10)  

Вот новый TestFunctions.setUpPersistence() метод:

public void setUpPersistence() throws ClassNotFoundException{
    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        Class<? extends TestFunctions> c = getClass();
        ClassLoader cl = c.getClassLoader();
        is = cl.getResourceAsStream("persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException i) {i.printStackTrace();}
    finally {if (is != null) {try {is.close();} catch (IOException ignored) {}}}//org.jvnet.hyperjaxb3.ejb.tests.po
    Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider");
    entityManagerFactory = Persistence.createEntityManagerFactory(/*"org.jvnet.hyperjaxb3.ejb.tests.po"*//*"persistence.xml"*/"org.jvnet.hyperjaxb3.ejb.tests.po", persistenceProperties);
}

Когда я заменяю Class c = Class.forName("org.eclipse.persistence.jpa.PersistenceProvider"); с Class c = Class.forName("org.hibernate.ejb.HibernatePersistence"); Я получаю похожую ошибку. Тем не мение, Class c = Class.forName("javax.persistence.spi.PersistenceProvider"); не выдает никакой ошибки, поэтому программа продолжается до тех же javax.persistence.PersistenceException: No Persistence provider for EntityManager named org.jvnet.hyperjaxb3.ejb.tests.po ошибка сбрасывается дальше вниз по течению.

Это говорит нам больше о причине ошибки? Также, hyperjaxb создает persistence.xml и помещает его в целевую папку. Эта ошибка произошла, когда persistence.xml был в этом месте, и сохранился, когда я переезжаю persistence.xml как показано выше. Является hyperjaxb вызывая эту проблему, не играя хорошо с затмением?

2 ответа

Решение

Я просто не могу удержаться, это моя последняя попытка помочь.:) Я пишу это для вас и для любых пользователей, которые могут столкнуться с подобными проблемами.

Я считаю, что у вас просто есть проблема в конфигурации проекта Eclipse. Пути в вашем проекте Eclipse не кажутся правильными.

Обычно, когда вы импортируете существующий проект Maven в Eclipse, используя File > Import... > Existing Maven Projects, m2eclipse следует проанализировать структуру проекта Maven и создать проект Eclipse с помощью (.classpath а также .project файлы) автоматически.

Пути в этих проектах взяты из вашего Eclipse pom.xml, Таким образом, вам на самом деле не следует создавать / изменять / добавлять / удалять / копировать / перемещать / какие-либо исходные папки Eclipse. Если вы сделаете это, ваш проект Eclipse больше не будет синхронизироваться с вашим проектом Maven, и вы получите действительно странные результаты.

Иногда m2eclipse не делает свою работу хорошо. Иногда вы не получаете правильные исходные папки, что-то пропадает и т. Д. По моему опыту, это значительно улучшилось с течением времени и сейчас m2eclipse работает как шарм. Из того, что я видел в вашей борьбе, может быть, у вас есть более старая версия m2eclipse, Может и нет, но я бы посоветовал все равно проверить.

Далее иногда m2eclispe все еще зажимы. В этом случае настоятельно рекомендуется сделать следующее:

  • Очистить проект: Project > Clean...
  • Обновите проект Maven (Alt + F5). Обязательно обновите конфигурацию проекта с pom.xml

Наконец, вы должны получить следующую структуру проекта:

В частности, вы должны получить следующие исходные папки:

  • src\main\java - исходная папка для ваших основных файлов Java
  • src\main\resources - исходная папка для ресурсов
  • target\generated-sources\xjc - исходная папка для сгенерированного кода.
    • Важно: не target\generated-sources как у вас есть, но target\generated-sources\xjc,
    • Эта папка содержит сгенерированные классы Java. (Hyperjaxb добавляет к ним аннотации JPA).
    • Он также содержит META-INF\persistence.xml который является дескриптором единицы персистентности. META-INF\persistence.xml ресурс определяется спецификацией JPA. Отсюда будет загружен блок персистентности.
    • Если вы сгенерировали тест туда и обратно (xml-to-db-and-back), то вы также увидите RoundtripTest класс где-то. Это тестовый класс JUnit, должна быть возможность выполнить его напрямую. (Run As > JUnit Test)
  • src\test\java - тестовые занятия.
  • src\test\resources - тестовые ресурсы

Это стандартная схема каталогов для проектов Maven. Единственная особенность target\generated-sources\xjc исходная папка, которая содержит код, сгенерированный компилятором схемы. И даже если это абсолютно стандартно, для плагинов генерации кода Maven принято создавать код в target\generated-sources\some-tool каталоги.

Ниже я размещаю .classpath файл из моего проекта:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry including="**/*.java" kind="src" output="target/classes" path="target/generated-sources/xjc">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="target/test-classes" path="src/test/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="output" path="target/classes"/>
</classpath>

Важный

Если у вас нет такой структуры каталогов (и ваши скриншоты показывают, что у вас ее нет), НЕ двигайтесь дальше. Это не удастся (это для вас). Сначала исправьте структуру вашего проекта. Не двигайтесь дальше, не пытайтесь запустить что-либо, вы столкнетесь со всевозможными странными вещами, такими как не найденные ресурсы и т. Д. (Что вы делаете).

Восстановить структуру проекта из pom.xml и очистить проект в Eclipse. Открыть свой .classpath файл и сравнить его построчно с тем, что я написал. Но, пожалуйста, сначала исправьте структуру проекта.

Далее, важно, чтобы вы понимали, что вы не должны перемещать или перетаскивать сгенерированный код. Это не правильно. Не делай этого. Пожалуйста, не двигайтесь дальше, пока вы не примете это как императив. Не перемещайте и не изменяйте сгенерированный код. Если вы это сделаете, вы перегоните ответственность за этот код. Вещи генерируются такими, какие они есть, потому что это работает таким образом. Поэтому, если вы измените его, очень вероятно, что он больше не будет работать (это не для вас). Если вам нужно что-то изменить, вы измените pom.xml который настраивает генерацию, а не результирующий код.

Теперь давайте проанализируем вашу текущую структуру проекта на основе следующего снимка экрана:

введите описание изображения здесь

Что я могу заметить:

  • src\main\java содержит maintest\Main а также TestFunctions, Если вы пытаетесь написать тест, поместите свои тестовые классы в src\test\javaне src\main\java,
  • src\main\resources содержит persistence.xml, sun-jaxb.episode, persistence.properties а также schema.xsd, Только schema.xsd должен быть там.
    • persistence.xml а также sun-jaxb.episode генерируются файлы. И, см. Выше, вы не должны перемещать их.
    • persistence.properties определяет соединение с базой данных, используемой для тестирования. Так должно быть в тестовых ресурсах, а именно src\test\resources, Положить его в src\main\resources наконец, добавит этот файл в получившийся JAR-файл, это все равно что сообщить всем имя пользователя и пароль базы данных, которую вы используете для тестирования
  • src\test\java - это нормально, но ваши тестовые занятия должны быть здесь.
  • src\test\resources - persistence.properties должен быть здесь.
  • target\generated-sources - это неправильно, это должно быть target\generated-sources\xjc
    • org.jvnet.hyperjaxb3.ejb.test.po пакет находится под target\generated-sources, Генерируется под target\generated-sources\xjcИтак, то, что я вижу, означает, что вы переехали. Не делай этого, см. Выше.
    • xjc отображается как пакет. Это фактически остаток после того, как вы (неправильно) настроили target\generated-sources как исходная папка. Эта папка должна содержать все сгенерированные источники, теперь она содержит только RoundtripTest, Это означает, что вы переместили сгенерированный код. Не делай этого, см. Императив выше.

Таким образом, ваша конфигурация проекта Eclipse, показанная выше, недействительна. Вот моя теория о том, почему это произошло. Я думаю что твой m2eclipse не обрабатывал pom.xml правильно, вы, вероятно, отсутствовали папки и т. д. Но вместо того, чтобы файлы проекта Eclipse были правильно сгенерированы, мой m2eclipse вы вручную добавили target\generated-sources и начал перемещать сгенерированный код. Это не правильный путь.

Пожалуйста, проверьте и перепроверьте .classpath пока это не эквивалентно тому, что я написал. Я заархивировал и загрузил свой пример проекта, который определенно работает для меня. Вы можете разархивировать и импортировать его, используя File > Import... > Existing Projects into Eclipse (не как проект Maven).

Наконец, вы должны быть в состоянии выполнить RoundtripTest как тест JUnit. Тест, вероятно, не пройден, но он должен быть запущен, вы не должны получать NPE и т. Д. У меня нет базы данных MySQL под рукой, поэтому сейчас я получаю следующее:

Detected [file:/C:/Projects/workspaces/hj3/hyperjaxb3-ejb-template-basic-0.6.0/target/classes/META-INF/persistence.xml].
    RoundtripTest

Loading entity manager factory properties.
    RoundtripTest

Loading entity manager factory properties from [file:/C:/Projects/workspaces/hj3/hyperjaxb3-ejb-template-basic-0.6.0/target/test-classes/persistence.properties].
    RoundtripTest

Could not obtain connection to query metadata
    org.hibernate.cfg.SettingsFactory

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.ConnectException
MESSAGE: Connection refused: connect

Это означает, что менеджер сущностей запущен правильно, но не может подключиться к базе данных. Если вы настроили тестовую базу данных в src\test\resources\persistence.properties Правильно, вы должны иметь возможность подключиться к базе данных. И если вы положите po.xml подать в src\test\samples, тест туда и обратно:

  • демонтировать эти файлы
  • сохранить в базу данных
  • загрузить его обратно
  • сравнить его с исходным результатом

Пожалуйста, сначала запустите тестирование в обе стороны, прежде чем начинать собственные эксперименты. Не копируйте код, не изменяйте его, не пытайтесь согнуть его в своей структуре каталогов. Он должен работать так, как есть. Не двигайся, пока это не произойдет.

Удачи.

Обновить.

Вы также можете столкнуться с проблемой неразрешенных зависимостей. Пожалуйста, убедитесь, что ваши зависимости разрешены правильно. Вот что я вижу:

Если вы этого не видите, это плохо. Что-то не так с вашим рабочим пространством. Проверьте, есть ли у вас сообщения об ошибках в Eclipse. Может быть, у вас есть что-то вроде:

Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:hibernate3-maven-plugin

Сначала быстро исправьте его ("Постоянно пометьте цель... как проигнорированное в билде Eclispe"). Не двигайтесь дальше, пока эта ошибка не исчезнет. Это блокировщик.

Параметр, который вы должны передать, является единицей постоянства. (Не имя файла.)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0" ... >
    <persistence-unit name="generated">
        <class>generated.Items</class>
        <class>generated.Items$Item</class>
        <class>generated.PurchaseOrderType</class>
        <class>generated.USAddress</class>
    </persistence-unit>
</persistence>

Так и должно быть generated для persistence.xml выше:

entityManagerFactory = Persistence.createEntityManagerFactory("generated", persistenceProperties);

Для вашей настойчивости должны быть:

entityManagerFactory = Persistence.createEntityManagerFactory("org.jvnet.hyperjaxb3.ejb.tests.po", persistenceProperties);
Другие вопросы по тегам