How to generate the JPA entity Metamodel?
It would be awesome if someone also knows the steps for setting this up in Eclipse (I assume it's as simple as setting up an annotation processor, but you never know)
Yes it is. Here are the implementations and instructions for the various JPA 2.0 implementations:
EclipseLink
org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor
Hibernate
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
- http://in.relation.to/2009/11/09/hibernate-static-metamodel-generator-annotation-processor
OpenJPA
org.apache.openjpa.persistence.meta.AnnotationProcessor6
- http://openjpa.apache.org/builds/2.4.1/apache-openjpa/docs/ch13s04.html
DataNucleus
org.datanucleus.jpa.JPACriteriaProcessor
- http://www.datanucleus.org/products/accessplatform_2_1/jpa/jpql_criteria_metamodel.html
The latest Hibernate implementation is available at:
- https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen/
An older Hibernate implementation is at:
- http://repository.jboss.com/maven2/org/hibernate/hibernate-jpamodelgen/1.0.0.Final/hibernate-jpamodelgen-1.0.0.Final.jar
How to use Hibernate JPA 2 Metamodel Generator?
But when I tried to generate these metamodel by run mvn compile, it only generated corresponding classes and a strange folder 'generated-sources' in target folder as below and does not generated corresponding java files in source folder.
The default folder for the generated meta classes is ${project.build.directory}/generated-sources/apt
where ${project.build.directory}
is target
by default. So the generated meta classes should be under target/generated-sources/apt
directory (as I can guess from your screenshot the meta classes are generated).
If you want to change this behavior you can configure the plugin to generate the meta classes to another folder by using the outputDirectory
element as follows:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<outputDirectory>${project.basedir}/generated</outputDirectory>
</configuration>
</execution>
</executions>
And don't forget to add the new folder into your class path otherwise your project might not build.
is this expected behavior?
yes
If yes, does it mean that I need to compile code before I use metamodel each time?
yes, but if you don't change or add new entities you can use the generaed classes provided you run mvn compile
at least once.
If no, how can I generate java files in source code folder?
I don't recommend to do it :-) I mean mixing the generated classes with the source code is not a good idea. If you don't like the target
folder use any other folder as described above.
How to generate JPA Metamodel with Gradle 5.x
you can just remove the plugin for the jpa modelgen and just use
annotationProcessor('org.hibernate:hibernate-jpamodelgen:<version>')
Addtionally i use those settings to configure where the generated code should live.
tasks.withType(JavaCompile) {
options.annotationProcessorGeneratedSourcesDirectory = file("src/generated/java")
}
sourceSets {
generated {
java {
srcDirs = ['src/generated/java']
}
}
}
Is it possible to generate hibernate metamodel for Java 11 and java modules?
It wasn't possible, now it is possible. I opened an issue for maven-processor-plugin
and they did necessary modification. So, use version 4.0-rc1+
and the following code:
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>4.0-rc1</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
<compilerArguments>-AaddGeneratedAnnotation=false</compilerArguments>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.4.14.Final</version>
</dependency>
</dependencies>
</plugin>
Edit:
This is the link to the issue.
JPA Static Metamodel not recognized by IntelliJ
To get IntelliJ IDEA to recognize the generated classes, I had to add this line on build.gradle
sourceSets {
main.java.srcDirs += 'build/generated/source/apt/main'
}
Update
Better solution is to modify IntelliJ Plugin
idea {
module {
sourceDirs += file("build/generated/source/apt/main")
generatedSourceDirs += file("build/generated/source/apt/main")
}
}
Generate the JPA metamodel files using maven-processor-plugin - What is a convenient way for re-generation?
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>
hibernate jpa metamodel generator: Problem with Filer: Attempt to recreate a file for type
I made some further investigations regarding the filer problem and here is what I found out (if you are in a hurry to find out about the solution of the filer problem just jump to the bottom of this answer).
Using the following dependencies in maven triggers automatic generation of jpa static metamodel when running "mvn compile":
<dependencies>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen-jakarta</artifactId>
<scope>provided</scope>
<version>5.6.12.Final</version>
</dependency>
</dependencies>
BTW: There's really nothing else to be done for jpa static metamodel generation.
But make sure to look at the right location for the generated code. You will find it under target/generated-sources/annotations
.
The filer problem occurs, if you have (a copy of) jpa static metamodel source code in your "usual" source code directory, e.g. src/main/java
. You can solve this if you delete the files in the source code directory.
If your IDE now complains about unresolvable types named *_, just add target/generated-sources/annotations
as source code folder in the IDE's build path.
Cheers!
Related Topics
Parsing Xml with Regex in Java
Difference in System. Exit(0) , System.Exit(-1), System.Exit(1 ) in Java
How to Schedule a Task to Run at Periodic Intervals
How to Sort an Arraylist of Objects by a Property
What Is the Significance of Load Factor in Hashmap
How to Remove Duplicate White Spaces in String Using Java
Increase the Java Heap Size Permanently
Where to Find Source Code for Java.Lang Native Methods
Java 8 Date and Time: Parse Iso 8601 String Without Colon in Offset
Filter Jacoco Coverage Reports with Gradle
How Can a Class Have a Member of Its Own Type, Isn't This Infinite Recursion
Safe String to Bigdecimal Conversion