Compile time validation for HQL and JPQL queries in Java code
Compile time validation for queries written in HQL, JPQL, and Panache.
This project now requires at least JDK 11, but JDK 15 or above is preferred.
Type ./gradlew
from this project directory.
This produces an artifact with the Maven coordinates
org.hibernate:query-validator:2.0-SNAPSHOT
in your local
Maven repository.
It also creates a far jar query-validator-2.0-SNAPSHOT-all.jar
in the build/libs
directory of this project.
The persistent entity classes must be annotated with the
basic JPA metadata annotations like @Entity
, @ManyToOne
,
@Embeddable
, @MappedSuperclass
, @ElementCollection
, and
@Access
. You may use XML-based mappings to specify database
mapping information like table and column names if that's what
you prefer. But entities mapped completely in XML will not be
discovered by the query validator.
query-validator-2.0-SNAPSHOT-all.jar
in the
compile-time classpath of your project. (Or depend on
org.hibernate:query-validator:2.0-SNAPSHOT
.)@CheckHQL
.The validator will check any static string argument of
createQuery()
, createSelectionQuery()
, and
createMutationQuery()
methods,@NamedQuery()
annotation, or@HQL
annotationwhich occurs in a package, class, or interface annotated
@CheckHQL
.
Inside a Panache entity or repository, the following queries will be checked:
list()
, find()
, and stream()
,count()
,delete()
, andupdate()
The purpose of the query validator is to detect erroneous query strings and query parameter bindings when the Java code is compiled, instead of at runtime when the query is executed.
A compile-time error is produced if:
Additionally, any JPA Query
instance that is created and
immediately invoked in a single expression will have its
parameter bindings validated. A warning is produced if:
setParameter()
, orsetParameter()
, but there
is no matching parameter in the query string.All Panache queries have their parameters validated.
When using a command line compiler, gradle
, or mvn
, errors
from the query validator are displayed in the compiler output
alongside other compilation errors.
javac
and ECJJust compile your code with javac
, or even with ECJ
(java -jar ecj-4.6.1.jar
), with the query validator jar
in
the classpath:
-classpath query-validator-2.0-SNAPSHOT-all.jar
Of course, you'll also need Hibernate core on the classpath.
In principle, it's enough to declare dependencies on Hibernate core and on the query validator, just like this:
dependencies {
implementation 'org.hibernate.orm:hibernate-core:6.3.0-SNAPSHOT'
annotationProcessor 'org.hibernate:query-validator:2.0-SNAPSHOT'
}
Unfortunately, this often results in some quite annoying warnings
from javac
. Get rid of them by also declaring an implementation
dependency on the Query validator:
dependencies {
implementation 'org.hibernate:query-validator:2.0-SNAPSHOT'
annotationProcessor 'org.hibernate:query-validator:2.0-SNAPSHOT'
implementation 'org.hibernate:query-validator:2.0-SNAPSHOT'
}
Maven handles annotation processors correctly. Just declare the dependency on the query validator:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>query-validator</artifactId>
<version>2.0-SNAPSHOT</version>
<optional>true</optional>
</dependency>
<dependencies>
Both IntelliJ and Eclipse require that annotation processing be explicitly enabled.
Select Enable annotation processing in IntelliJ IDEA preferences under Build, Execution, Deployment > Compiler > AnnotationProcessors.
You do not need to do this if you're using Gradle to build your project.
IntelliJ only runs annotation processors during a build (that
is, when you Run
your code or explicitly Build Project
).
So you won't see errors in your Java editor as you're typing.
Eclipse IDE doesn't load annotation processors from the project classpath. So you'll need to add the query validator manually.
build/libs/query-validator-2.0-SNAPSHOT-all.jar
from this project directory.Your project properties should look like this:
Eclipse runs annotation processors during every incremental
build (that is, every time you Save
), so you'll see errors
displayed inline in your Java editor.
If the query validator doesn't run, please ensure that:
The query validator was developed and tested with:
Other versions of javac
, ECJ, and Hibernate may or may not
work. The query validator depends on internal compiler APIs in
javac
and ECJ, and is therefore sensitive to changes in the
compilers.
Please be aware of the following issues.
Queries are interpreted according to Hibernate's flavor of JPQL (i.e. HQL), which is a superset of the query language defined by the JPA specification. Queries accepted by the query validator may not execute correctly on other implementations of JPA.
In ECJ, don't use @Entity(name="Whatever")
, since, during an
incremental build, the processor won't be able to discover the
entity named Whatever
. Just let the entity name default to
the name of the class.
Please report ugly, confusing, or badly-formatted error messages as bugs.