Как правильно улучшить классы во время сборки с помощью Maven? OpenJPA

Я пытаюсь улучшить классы (сущностей), поэтому я не получу это исключение:

Exception in thread "main" <openjpa-3.1.2-r66d2a72 nonfatal user error> org.apache.op
enjpa.persistence.ArgumentException: Attempt to cast instance "entities.EntityPerson@
6dba847b" to PersistenceCapable failed.  Ensure that it has been enhanced.
FailedObject: entities.EntityPerson@6dba847b
    at org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.java:486
3)
    at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2762)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2707)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2690)
    at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2592)
    at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1197)
    at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:8
37)
    at openjpa.Test/main.Main.main(Main.java:23)

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

Я следовал этому: https://openjpa.apache.org/enhancement-with-maven.html на официальной странице openjpa и добавил openjpa-maven-plugin в раздел моего pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>registry</groupId>
    <artifactId>datalayer</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.sourceEncoding>UTF-8</project.reporting.sourceEncoding>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.openjpa</groupId>
                    <artifactId>openjpa-maven-plugin</artifactId>
                    <version>3.1.2</version>
                    <configuration>
                        <includes>datalayer/dto/*.class</includes>
                        <addDefaultConstructor>true</addDefaultConstructor>
                        <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
                    </configuration>
                    <executions>
                        <execution>
                            <id>enhancer</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>enhance</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.15.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbytools</artifactId>
            <version>10.15.2.0</version>
        </dependency>
    </dependencies>
</project>

, но я все еще получаю это исключение. Я использую Eclipse и встроенную команду Run As -> Maven install. Я также пытался запустить mvn install из командной строки. Затем я просто пытаюсь сохранить некоторую сущность, используя EntityManager.

Запуск mvn install с плагином openjpa-maven и без него ничего не меняет (один и тот же .jar сгенерирован с теми же файлами .class, тот же вывод maven на консоль)

Как сказано в ответе, мне нужно было выполнить openjpa:enhance цель при сборке с помощью Maven. Я де-факто не использовал openjpa-maven-plugin, поэтому исправил это. Вывод Maven:

[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< registry:datalayer >-------------------------
[INFO] Building datalayer 0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ datalayer ---
[INFO] Deleting C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Openjpa.Test\target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ datalayer ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ datalayer ---
[WARNING] Can't extract module name from geronimo-jms_1.1_spec-1.1.1.jar: geronimo.jm
s.1.1.spec: Invalid module name: '1' is not a Java identifier
[WARNING] Can't extract module name from geronimo-jta_1.1_spec-1.1.1.jar: geronimo.jt
a.1.1.spec: Invalid module name: '1' is not a Java identifier
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Op
enjpa.Test\target\classes
[INFO] 
[INFO] --- openjpa-maven-plugin:3.1.2:enhance (default-cli) @ datalayer ---
130  DataLayer  INFO   [main] openjpa.Tool - Enhancer running on type "class entities
.EntityPerson".
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ datalayer ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ datalayer ---
[WARNING] Can't extract module name from geronimo-jms_1.1_spec-1.1.1.jar: geronimo.jm
s.1.1.spec: Invalid module name: '1' is not a Java identifier
[WARNING] Can't extract module name from geronimo-jta_1.1_spec-1.1.1.jar: geronimo.jt
a.1.1.spec: Invalid module name: '1' is not a Java identifier
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Op
enjpa.Test\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ datalay
er ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ datalayer 
---
[WARNING] Can't extract module name from geronimo-jta_1.1_spec-1.1.1.jar: geronimo.jt
a.1.1.spec: Invalid module name: '1' is not a Java identifier
[WARNING] Can't extract module name from geronimo-jms_1.1_spec-1.1.1.jar: geronimo.jm
s.1.1.spec: Invalid module name: '1' is not a Java identifier
[INFO] Changes detected - recompiling the module!
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ datalayer ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ datalayer ---
[INFO] Building jar: C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Openjpa.Test\tar
get\datalayer-0.0.1.jar
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ datalayer ---
[INFO] Installing C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Openjpa.Test\target
\datalayer-0.0.1.jar to C:\Users\wortigson\.m2\repository\registry\datalayer\0.0.1\da
talayer-0.0.1.jar
[INFO] Installing C:\Users\wortigson\Desktop\ISMatrikaBcWorkspace\Openjpa.Test\pom.xm
l to C:\Users\wortigson\.m2\repository\registry\datalayer\0.0.1\datalayer-0.0.1.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

Вы можете видеть, что я запускаю энхансер в классе EntityPerson, который представляет собой простой объект JPA, на котором я это тестировал. Однако я все еще получаю это исключение. Я заметил, что maven-compiler-plugin:3.8.1:compile работает дважды. До и после openjpa-maven-plugin:3.1.2:enhance может быть проблема?

Я думаю, что это не мой случай: Как улучшить класс из отдельного jar-файла во время сборки с помощью openJPA?

Обнаружен обходной путь попытка приведения экземпляра на PersistenceCapable не удалось. Убедитесь, что он был улучшен , установив какой-либо атрибут в конфигурации, как говорится в принятом ответе, но я не хочу делать это таким образом, поскольку в первом комментарии говорится, что это не рекомендуется, и указывает на официальную страницу openjpa, где я нашел этот пример, как улучшить классы во время сборки maven, но, как я уже писал, это не работает.

Основной метод тестирования:

public static void main(String[] args)
    {
        HashMap<String, String> jpaProps = new HashMap<String, String>();
        jpaProps.put("javax.persistence.jdbc.url", "jdbc:derby:testDB;create=true");
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("DataLayer", jpaProps);
        EntityManager manager = factory.createEntityManager();
        EntityPerson person = new EntityPerson();
        person.setAge(25);
        person.setName("Andrej Hruska");
        manager.persist(person); // +
    }

Класс EntityPerson:

package entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class EntityPerson
{
    @Id
    @GeneratedValue
    private long id;
    
    @Column(nullable = false)
    private String name;
    
    private int age;

    public long getId()
    {
        return id;
    }

    public void setId(long id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }
}

постоянство.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence https://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_2.xsd">
    <persistence-unit name="DataLayer"
        transaction-type="RESOURCE_LOCAL">
        <non-jta-data-source>DataSource</non-jta-data-source>
        <properties>
            <property
                name="javax.persistence.schema-generation.database.action"
                value="create" />
            <property name="javax.persistence.jdbc.driver"
                value="org.apache.derby.jdbc.EmbeddedDriver" />
            <property name="javax.persistence.jdbc.url"
                value="jdbc:derby:db;create=true" />
        </properties>
    </persistence-unit>
</persistence>

Структура проекта:

Структура проекта

Действия для воспроизведения:

  1. Проект Crete Maven в Eclipse
  2. Скопируйте мой pom.xml (или добавьте зависимости к derby, openjpa и настройте свой плагин openjpa-maven, имена и пути)
  3. Скопируйте мой файл persistence.xml (или создайте свой собственный с каким-либо блоком сохранения)
  4. Скопируйте мой класс EntityPerson (или создайте простой объект JPA для его проверки)
  5. Запустите mvn clean compile openjpa:enhance install (важная часть — openjpa:enhance)
  6. Попробуйте сохранить сущность, как я сделал в своем основном методе.

person Wortig    schedule 04.03.2021    source источник


Ответы (3)


Переместите определение плагина с <pluginManagement> на <plugins>, например

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>registry</groupId>
    <artifactId>datalayer</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.sourceEncoding>UTF-8</project.reporting.sourceEncoding>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
                <plugin>
                    <groupId>org.apache.openjpa</groupId>
                    <artifactId>openjpa-maven-plugin</artifactId>
                    <version>3.1.2</version>
                    <configuration>
                        <includes>datalayer/dto/*.class</includes>
                        <addDefaultConstructor>true</addDefaultConstructor>
                        <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
                    </configuration>
                    <executions>
                        <execution>
                            <id>enhancer</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>enhance</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
       </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.15.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbytools</artifactId>
            <version>10.15.2.0</version>
        </dependency>
    </dependencies>
</project>

PluginManagement предназначен только для настройки — плагины не запускаются автоматически.

person J Fabian Meier    schedule 09.03.2021

Несколько недоразумений.

Я пробовал использовать только openjpa-maven-plugin без maven-compiler-plugin, но это не помогло.

Maven pom.xml считается объектной моделью проекта. Это означает, что для вашего проекта это объект, который моделирует процесс сборки. Этот объект является подклассом родительского pom.xml, встроенного в Maven, который определяет сборку по умолчанию; поэтому, если вы удалите плагин maven-compiler-plugin, вы получите конфигурацию плагина maven-compiler-plugin по умолчанию. Скорее всего, конфигурация довольно старая, поставляется с Maven, и вам, вероятно, лучше включить переопределение, которое обновит ее.

Эклипс и Мавен

Eclpise и Maven работают вместе; но, пока вы не узнаете, как они работают вместе, у вас будет много проблем.

Eclipse читает файл pom.xml и создает файл Eclipse configuration, который должен выполнять те же действия, что и файл pom.xml, теми же способами. Когда вы компилируете с помощью Eclipse, он не запускает mvn compile, он строит конфигурацию Eclipse, которая может быть старше, чем недавно отредактированная pom.xml. По этой причине вам следует перечитывать конфигурацию вашего проекта после каждого редактирования pom.xml при использовании ecplise.

Если вы хотите взглянуть на другую IDE, похожую на Eclipse; но тот, который вызывает mvn compile вместо того, чтобы вызывать свою интерпретированную версию, должен быть таким же, но часто это не так, посмотрите на NetBeans. https://netbeans.apache.org/download/nb122/index.html В отличие от Ecplipse, он не содержит собственного зеркального отображения команд для плагинов Maven (или собственного встроенного компилятора), он использует команду mvn и компилятор javac и запускает их с конфигурациями для генерации множества выходных сообщений, которые он затем читает, чтобы обновить его сторону IDE.

Причина, по которой я указываю на это, заключается в том, что вы можете следовать инструкциям, и если вы это сделаете, вы можете увидеть правильный вывод на mvn package из командной строки, но не в Eclipse (из-за необходимости обновить проект eclipse из источник pom.xml)

person Edwin Buck    schedule 06.03.2021
comment
Я попытался mvn package из командной строки, однако результат тот же - тот же файл .jar с теми же файлами .class. Я предполагаю, что цель улучшения может быть каким-то образом пропущена на этапе классов процессов, или путь <includes> действительно неверен. - person Wortig; 06.03.2021

Вам нужно сказать maven запустить цель повышения.

mvn clean compile openjpa:enhance

Вы должны увидеть этот вывод:

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ jpa-example ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/gordon/docs/programming/openjpa/jpa-example/target/classes
[INFO] 
[INFO] --- openjpa-maven-plugin:3.1.2:enhance (default-cli) @ jpa-example ---
[INFO] 

В maven есть иерархия. В верхней части находятся жизненные циклы, состоящие из фаз, которые реализуются как цели плагина. Упаковка определяет цели фазы.

Цель улучшения не является одной из целей по умолчанию для сборки или компиляции.

В eclipse, если вы измените pom.xml, вам нужно щелкнуть правой кнопкой мыши и выбрать Maven->Update Project. Вы можете поместить свой openjpa:enhance в поле целей в конфигурациях запуска eclipse для Maven Build.

Конфигурация запуска Maven Build

person Gordon Tytler    schedule 06.03.2021
comment
Ты спаситель! Цель улучшения, кажется, выполняется, однако я получаю сообщение об ошибке сборки: justpaste.it/5ws66. У меня есть файл META-INF/persistence.xml, и он находится в моем пути к классам. Можете ли вы показать структуру вашего проекта? - person Wortig; 07.03.2021
comment
Мой файл находится в src/main/resources/META-INF, и у меня есть это в моем pom.xml `‹resources› ‹resource› ‹directory›src/main/resources‹/directory› ‹/resource› ‹/resources› ‹ /сборка›` - person Gordon Tytler; 07.03.2021
comment
Добавление этого ресурса в pom.xml помогло, но теперь я получаю сообщение об ошибке при попытке проанализировать этот файл: justpaste.it/7ihlc . У вас есть идеи, что может быть не так? Eclipse не предупреждает об ошибках в этом файле. Можете ли вы описать свой файл persistence.xml? - person Wortig; 07.03.2021
comment
@Wortig Я думаю, что это безопасность Oracle изменить. Вам нужно xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence https://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_2.xsd" - person Gordon Tytler; 07.03.2021