如何在构建时使用 Maven 正确增强类?开放式JPA [英] How to enhance classes properly at build time using Maven? OpenJPA

查看:88
本文介绍了如何在构建时使用 Maven 正确增强类?开放式JPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试增强(实体)类,所以我不会得到这个异常:

线程main"中的异常<openjpa-3.1.2-r66d2a72 非致命用户错误>org.apache.openjpa.persistence.ArgumentException:尝试强制转换实例entities.EntityPerson@"6dba847b"到 PersistenceCapable 失败.确保它已得到增强.失败对象:entities.EntityPerson@6dba847b在 org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.java:4863)在 org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2762)在 org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2707)在 org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2690)在 org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2592)在 org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1197)在 org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:837)在 openjpa.Test/main.Main.main(Main.java:23)

说我尝试保留的实例没有增强.

我遵循了这个:

重现步骤:

  1. Eclipse 中的 Crete Maven 项目
  2. 复制我的 pom.xml(或将依赖项添加到 derby、openjpa 并设置您的 openjpa-maven-plugin、名称和路径)
  3. 复制我的persistence.xml(或使用一些持久性单元创建自己的)
  4. 复制我的 EntityPerson 类(或创建简单的 JPA 实体以对其进行测试)
  5. 运行 mvn clean compile openjpa:enhance install(重要的部分是 openjpa:enhance)
  6. 尝试像我在主方法中所做的那样持久化实体

解决方案

将插件定义从 移到 like

<modelVersion>4.0.0</modelVersion><groupId>注册表</groupId><artifactId>数据层</artifactId><version>0.0.1</version><包装>罐</包装><属性><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></属性><构建><插件管理><插件><插件><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version></插件></plugins></pluginManagement><插件><插件><groupId>org.apache.openjpa</groupId><artifactId>openjpa-maven-plugin</artifactId><version>3.1.2</version><配置><includes>datalayer/dto/*.class</includes><addDefaultConstructor>true</addDefaultConstructor><enforcePropertyRestrictions>true</enforcePropertyRestrictions></配置><执行><执行><id>增强器</id><阶段>流程类</阶段><目标><目标>增强</目标></目标></执行></执行></插件></plugins></build><依赖项><依赖><groupId>org.apache.openjpa</groupId><artifactId>openjpa</artifactId><version>3.1.2</version></依赖><依赖><groupId>org.apache.derby</groupId><artifactId>德比</artifactId><version>10.15.2.0</version></依赖><依赖><groupId>org.apache.derby</groupId><artifactId>derbytools</artifactId><version>10.15.2.0</version></依赖></依赖项></项目>

PluginManagement 仅用于配置——插件不会自动运行.

I am trying to enhance (entities) classes so i will not get this Exception:

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)

saying that my instance i am trying to persist is not enhanced.

I have followed this: https://openjpa.apache.org/enhancement-with-maven.html official openjpa page and added openjpa-maven-plugin to the section of my 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>

, but i still get that exception. I am using Eclipse and built in command Run As -> Maven install. I also tried to run mvn install from command line. Then i just try to persist some entity using EntityManager.

Running mvn install with and without openjpa-maven-plugin does not change anything (same .jar generated with same .class files, same maven output to console)

As answer says, i needed to run openjpa:enhance goal when building with Maven. I was de facto not using openjpa-maven-plugin, so i fixed that. Maven output:

[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

You can see i run enhancer on EntityPerson class, which is simple JPA entity i tested this on. However i still get that Exception. I noticed maven-compiler-plugin:3.8.1:compile running twice. Before and after openjpa-maven-plugin:3.1.2:enhance - might this be problem?

I think this is not my case: How to enhance a class from a separate jar at build time with openJPA?

Found there is workaround Attempt to cast instance to PersistenceCapable failed. Ensure that it's been enhanced by setting some attribute in configuration as accepted answer says, but i do not want to do it that way, as first comment says it is not recommended and points to the official openjpa page, where i found that example how to enhance classes during maven build time, but as i wrote, it does not work.

Testing main method:

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 class:

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;
    }
}

persistence.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>

Project structure:

Steps to reproduce:

  1. Crete Maven project in Eclipse
  2. Copy my pom.xml (or add dependencies to derby, openjpa and set up your openjpa-maven-plugin, names and paths)
  3. Copy my persistence.xml (or create your own with some persistence unit)
  4. Copy my EntityPerson class (or create simple JPA entity to test it on)
  5. Run mvn clean compile openjpa:enhance install (important part is openjpa:enhance)
  6. Try to persist entity as i did in my main method

解决方案

Move the plugin definition to from <pluginManagement> to <plugins> like

<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 is only for configuration -- the plugins are not run automatically.

这篇关于如何在构建时使用 Maven 正确增强类?开放式JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆