Skip to content

Project configuration woes

Yesterday, my Java project stopped compiling. After making some small changes, the compiler spewed a hundred errors about JPA metamodel classes it could not find before giving up. Of course, I did not change anything™ in conjunction with JPA stuff!

I'll quickly explain what happened, so you can hopefully quickly walk out of this trap in case you should experience the same.

The technical background

JPA (Java persistence API) metamodel classes are classes that describe the structure of JPA entity classes (classes used to store database state as Java objects). They enable you to write Java code for creating database queries in a typesafe way. Using them, you can avoid using Strings as entity or property names, or avoid casting result values to the correct Java type. The Java source code of those classes is typically generated by the JPA provider (for example Hibernate) by looking at the source code of your JPA entity classes.

We're generating those classes using the Hibernate's jpamodelgen annotation processor and use IntelliJ as IDE for development. The project is built by Apache Maven, and IntelliJ should pick up its project configuration from the pom.xml file.

Looking for a way out

Since we had experienced difficulties with the metamodel generation by IntelliJ some years ago, I first tried the maven build directly:

mvn clean compile

The compiler again spewed a hundred errors at me, then gave up. So, at least IntelliJ is not to blame here.

I looked at the pom.xml, where we have in the dependencies part

    <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.4.30.Final</version>
</dependency>

and no special compiler plugin configuration for annotation processing, just

    <plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin}</version>
<configuration>
<release>${version.java}</release>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>

in the build/plugins part. Both have been there for ages (in terms of project development scale), so also apparently none of the venerable colleagues were to blame, either. Must have been my fault, then. At least, fortunately, the problem should be solvable without any social interaction.

Keep it correct, stupid!

To reassure myself, I started searching the web for ways to do the JPA metamodel creation. I found many different solutions depending on the Java and Hibernate version number era they were written in. That's why this only increased my puzzlement and did not help a lot. But since the project compiled fine until one or two hours before, I had confidence the pom.xml file was ok.

Only then I looked at the error output (because it was large and consisted mostly of the same messages). Among all those errors like

[ERROR] src/main/java/.../FactSheetDAO.java:[206,69] cannot find symbol
[ERROR] symbol: variable FactSheet_
[ERROR] location: class ....FactSheetDAO

I spotted one that was different:

[ERROR] src/main/java/.../MetaModelActionsJob.java:[20,53] 
wrong number of type arguments; required 2

The compiler had given up after 100 errors, and I think I was lucky that this different message was among the first 100.

I had indeed introduced a second type parameter to a base class without adapting one of the derived classes:

AbstractJob.java:
public abstract class AbstractJob<T, P> implements Callable<T>, ProgressIndicator, JobMigration<T>

MetaModelActionsJob.java:
public class MetaModelActionsJob extends AbstractJob<MetaModelActionsJobResult>

After I fixed that to

public class MetaModelActionsJob extends AbstractJob<MetaModelActionsJobResult, Void>

the project compiled again successfully, including the source code generation for the metamodel classes. Yay!

To summarize

  • Some errors in the Java source code can confuse the jpamodelgen annotation processor enough to not be able to generate the source code of the JPA metamodel classes.
  • Metamodel classes are usually used in many queries, so if they are missing, this creates a lot of compiler errors.
  • The swamp of compiler errors makes it hard to find the real errors in the code, so it's hard to find the root cause.
  • More so if you get scared of the large number of errors and want to investigate them first.

Advice

If metamodel class generation stops working, it's not necessarily a fault in the project configuration (build tool or IDE). It can as well be an error in your Java code. In my case, it was the missing generics type parameter.

Image of the author

Published by Dirk L.

Visit author page