Generate the JPA metamodel files using maven-processor-plugin - What is a convenient way for re-generation?
Asked Answered
E

4

11

I am trying to use maven-processor-plugin for generating JPA metamodel java files and I set up my pom.xml as belows.

<plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <compilerArgument>-proc:none</compilerArgument>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
            <execution>
                <id>process</id>
                <goals>
                    <goal>process</goal>
                </goals>
                <phase>generate-sources</phase>
                <configuration>
                    <!-- source output directory -->
                    <outputDirectory>${basedir}/src/main/java</outputDirectory>
                    <processors>
                        <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                    </processors>
                    <overwrite>true</overwrite>
                </configuration>
            </execution>
        </executions>
    </plugin>

Actually, I want to generate metamodel files (Entity_.java) to the same packages of their corresponding entities (Entity.java). Hence, I set up outputDirectory in the plugin as

<outputDirectory>${basedir}/src/main/java</outputDirectory>

The first time of running is ok, but from later times when performing the metamodel java files re-generation, the plugin always turns out an error about file duplication.

My Question is - Is there any way to config the plugin so that it could overwrite the existing files during re-generation?

In fact, to work around

  1. I must delete all generated files before any re-generation.
  2. I could point the outputDirectory to a different folder in /target, this location will be clean everytime Maven run, but this leads to manually copy generated metamodel files to source folder for update after re-generation.

Both of these are very inconvenient and I hope you guys could show me a proper solution.

Epicalyx answered 10/6, 2015 at 18:17 Comment(0)
U
10

The proper solution is that generated sources should be in the target folder and shouldn't be put into the source-folders nor your SCM system.

Of course, by putting your generated sources into target, you would face the problem within your IDE because the related code can't be found. Therefore you can add the build-helper-maven-plugin to dynamically add the folder from the target directory.

<plugin>
    <groupId>org.bsc.maven</groupId>
    <artifactId>maven-processor-plugin</artifactId>
    <executions>
        <execution>
            <id>process</id>
            <goals>
                <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <!-- source output directory -->
                <outputDirectory>${project.build.directory}/generated-sources/java/jpametamodel</outputDirectory>
                <processors>
                    <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                </processors>
                <overwrite>true</overwrite>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/java/jpametamodel</source>
                </sources>
            </configuration>
        </execution>
    </executions>
 </plugin>
Unciform answered 11/6, 2015 at 6:47 Comment(3)
Thank Martin for your explanation !!! With using build-helper-maven-plugin and installing a bundle of corresponding eclipse plugins, now my IDE could resolve the external generated files as Java classes which could be referenced from anywhere in my codeNimiety
The build-helper-meven-plugin is too old to be used according to this post. Is there an updated method? I run Maven 3.3.3.Platitude
This is a good solution... Implementation specific ~ Intellij supports adding annotation processorsRegeniaregensburg
J
13

March 2018 Answer with Hibernate 5

As described on https://docs.jboss.org/hibernate/orm/5.0/topical/html/metamodelgen/MetamodelGenerator.html:

Simply add this to <project> <dependencies> ... </dependencies> </project> in your pom.xml:

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-jpamodelgen</artifactId>
    <version>5.2.16.Final</version>
    <scope>provided</scope>
</dependency>

There is nothing else that should be necessary for you to do. If you run into issues, visit the jboss page at the top of this answer.

The version included in this snippet is the latest version as of March, 2018, but check the artifact page (https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen) for the latest version.

This is not intended to be an original answer, but should prove helpful to anyone who wants a simple, straightforward copy-pastable solution.

Jongjongleur answered 29/3, 2018 at 8:48 Comment(1)
Was not working. I had to do this + add what walkeros said.Heinz
U
10

The proper solution is that generated sources should be in the target folder and shouldn't be put into the source-folders nor your SCM system.

Of course, by putting your generated sources into target, you would face the problem within your IDE because the related code can't be found. Therefore you can add the build-helper-maven-plugin to dynamically add the folder from the target directory.

<plugin>
    <groupId>org.bsc.maven</groupId>
    <artifactId>maven-processor-plugin</artifactId>
    <executions>
        <execution>
            <id>process</id>
            <goals>
                <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
                <!-- source output directory -->
                <outputDirectory>${project.build.directory}/generated-sources/java/jpametamodel</outputDirectory>
                <processors>
                    <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
                </processors>
                <overwrite>true</overwrite>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/java/jpametamodel</source>
                </sources>
            </configuration>
        </execution>
    </executions>
 </plugin>
Unciform answered 11/6, 2015 at 6:47 Comment(3)
Thank Martin for your explanation !!! With using build-helper-maven-plugin and installing a bundle of corresponding eclipse plugins, now my IDE could resolve the external generated files as Java classes which could be referenced from anywhere in my codeNimiety
The build-helper-meven-plugin is too old to be used according to this post. Is there an updated method? I run Maven 3.3.3.Platitude
This is a good solution... Implementation specific ~ Intellij supports adding annotation processorsRegeniaregensburg
M
8

In case you your have another annotation processor used during compilation (like lombok) you might run into following error (depite having hibernate-jpamodelgen added as dependency):

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /your/not/CompilableClass:[5,68] cannot find symbol
  symbol:   class YouEntity_
  location: package your.not
[INFO] 1 error

In this case you need to declare both annotation processors directly for your compiler plugin (for both lombok and hibernate):

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.hibernate</groupId>
                            <artifactId>hibernate-jpamodelgen</artifactId>
                            <version>${hibernate-jpamodelgen.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
Multistage answered 18/1, 2021 at 11:47 Comment(1)
I had no error but this did the trick, thank you.Heinz
H
2

i have also a working solution and i want to share this one with others. so i hope that is the correct place for this.

the code can be found at GitHub https://github.com/StefanHeimberg/jpa21-maven-metagen

features:

  • JPA 2.1
  • Example with Hibernate Metamodel Generator
  • Example with EclipseLink Metamodel Generator
  • Minimal Maven configuration for IntelliJ (Tested with 14.1.4) and NetBeans (Tested with 8.1)
  • M2E Workaround for Eclipse (Tested with 4.5.1) (Automatic profile activation)

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github.stefanheimberg</groupId>
    <artifactId>jpa21-maven-metagen</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

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

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>hibernate</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <hibernate.version>5.0.3.Final</hibernate.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.hibernate</groupId>
                    <artifactId>hibernate-jpamodelgen</artifactId>
                    <version>${hibernate.version}</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </profile>

        <profile>
            <id>eclipselink</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <eclipselink.version>2.6.1</eclipselink.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.eclipse.persistence</groupId>
                    <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
                    <version>${eclipselink.version}</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </profile>

        <profile>
            <id>m2e</id>
            <activation>
                <property>
                    <name>m2e.version</name>
                </property>
            </activation>
            <build>
                <pluginManagement>
                    <plugins>
                        <!--This plugin's configuration is used to store Eclipse m2e settings 
                        only. It has no influence on the Maven build itself. -->
                        <plugin>
                            <groupId>org.eclipse.m2e</groupId>
                            <artifactId>lifecycle-mapping</artifactId>
                            <version>1.0.0</version>
                            <configuration>
                                <lifecycleMappingMetadata>
                                    <pluginExecutions>
                                        <pluginExecution>
                                            <pluginExecutionFilter>
                                                <groupId>
                                                    org.codehaus.mojo
                                                </groupId>
                                                <artifactId>
                                                    build-helper-maven-plugin
                                                </artifactId>
                                                <versionRange>
                                                    [1.9.1,)
                                                </versionRange>
                                                <goals>
                                                    <goal>add-source</goal>
                                                </goals>
                                            </pluginExecutionFilter>
                                            <action>
                                                <execute>
                                                    <runOnConfiguration>true</runOnConfiguration>
                                                    <runOnIncremental>true</runOnIncremental>
                                                </execute>
                                            </action>
                                        </pluginExecution>
                                    </pluginExecutions>
                                </lifecycleMappingMetadata>
                            </configuration>
                        </plugin>
                    </plugins>
                </pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>build-helper-maven-plugin</artifactId>
                        <version>1.9.1</version>
                        <executions>
                            <execution>
                                <id>add-source</id>
                                <phase>generate-sources</phase>
                                <goals>
                                    <goal>add-source</goal>
                                </goals>
                                <configuration>
                                    <sources>
                                        <source>${project.build.directory}/generated-sources/annotations/</source>
                                    </sources>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>
Heber answered 11/11, 2015 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.