4.30.2015

How to use QueryDSL with JPA, Gradle and IDEA

QueryDSL is cool Database Query DSL for Java. I will recommend you to check it if you still don't know what is it. But there are not so much information on how to use it with Gradle. Also, it's not so clear about Intellij IDEA integration. With this article I would like to point you on querydsl-apt and Java annotations processors discovery.

Similar to projects like Lombok since version 2.7.1 QueryDSL has support for Java annotation processors discovery: https://github.com/querydsl/querydsl/issues/180. It means that we don't have to configure code generation manually, javac will pick up annotation processor automagically.

Gradle

Gradle setup is really easy. You can start with example project created by me: https://github.com/bsideup/querydsl-gradle-idea/tree/10ffd70805e3a7951d4614ff4f7e27102fdad343

build.gradle is simple:


We're declaring dependency on querydsl-apt:3.6.3 with jpa classifier. It contains Java Annotation Processor for JPA annotations like @Entity. If you already have a project with QueryDSL and just want to improve your Gradle build - just remove everything related to QueryDSL code generation and just add this dependency.

Now you can build your project:

$ ./gradlew build
:compileJava
Note: Running JPAAnnotationProcessor
Note: Serializing Entity types
Note: Generating ru.trylogic.querydsl.example.QUser for [ru.trylogic.querydsl.example.User]
Note: Running JPAAnnotationProcessor
Note: Running JPAAnnotationProcessor
:processResources
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 2.768 secs

There are notes about annotation processing from JPAAnnotationProcessor. It means that everything works as expected and code was generated. Easy, huh?

IntelliJ IDEA

But we don't want to build our project with Gradle during development, we want to use build from IDEA! First, change your build.gradle file:


Now open project in IDEA (if you didn't import project yet you can easily open build.gradle file in IDEA, it will propose you to import it). For some reasons IDEA will not enable annotation processing by default when you import your Gradle project, so you need to enable it.

  1. Go to Preferences -> Build, Execution, Deployment -> Annotation Processors;
  2. Check Enable annotation processing checkbox;
  3. In "Store generated sources relative to:" select Module content root.
Now if you will build your project, QueryDSL will generate code for your entities and you will be able to use it like this:



As always, full sources can be found here: http://github.com/bsideup/querydsl-gradle-idea/

12 comments:

  1. In gradle snippet, which configures idea project, "generatedSourcesDir" can be added to additionally mark sources as generated:

    ```
    idea {
    module {
    sourceDirs += file('generated/')
    generatedSourceDirs += file('generated/')
    }
    }
    ```

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  2. I had a quick question... After i have generated the metamodel classes do i need to copy and paste them to use them. currently i am able to see it being genrated in src/jpaModelgen/... package but I am not bale to use it in my code. Is their anything that I am doing wrong or how would i change the place where the files are getting generated in gradle.

    ReplyDelete
    Replies
    1. I may be a little late with this reply, but I had the same issue and the key for me was to make sure that you add :jpa to the end of the apt compile definition in your gradle.build file:

      compile('com.querydsl:querydsl-apt:4.0.7:jpa')

      Delete
  3. How to force querydsl to generate its metamodel from entities coming from jar included in the project dependencies?

    ReplyDelete
  4. Generated model is not in the generated/ path it is in the build/classes/main/com/... - do you know how to change it?

    ReplyDelete
  5. Hi, i am using your setup, but if i execute the build task i get

    ./gradlew build
    :compileGeneratedJava UP-TO-DATE
    :compileGeneratedScala UP-TO-DATE
    :processGeneratedResources UP-TO-DATE
    :generatedClasses UP-TO-DATE
    :compileJava UP-TO-DATE
    :compileScala UP-TO-DATE
    :processResources UP-TO-DATE
    :classes UP-TO-DATE

    why is

    Note: Running JPAAnnotationProcessor
    Note: Serializing Entity types ... and so on missing.
    What can cause that problem ?

    ReplyDelete
  6. To make generated classes visible in IDEA I marked build/generated-sources/ folder as Sources (before I removed build/ folder from Excluded folders and then added all except generated-sources/ to Excluded folders) in File->Project structure. Grade apply plugin solution don't work for me.

    Gradle wrapper version: 2.8
    IntelliJ IDEA Ultimate version: 15.0.3

    ReplyDelete
  7. I tried to put compile "com.mysema.querydsl:querydsl-apt:3.7.0:jpa", but I get Could not find querydsl-apt-jpa.jar file:~/.m2/repository/com/mysema/querydsl/querydsl-apt/3.7.0/querydsl-apt-3.7.0-jpa.jar

    ReplyDelete
  8. I also have problem to specify the output directory, until i found this gradle plugin https://github.com/ewerk/gradle-plugins/tree/master/plugins/querydsl-plugin, works perfectly, you really should give it a try

    ReplyDelete
  9. test cases that query dsl works fine but IntelliJ editor pane reports a error: Q classes cannot be resolved. I don't know why ..

    ReplyDelete
  10. First off, really good article. It got me off the ground running pretty quick.

    I have a quick question tho. I'm running a Spring Boot application using Spring Data and Hibernate as the transaction manager. Should I be using a different set of querydsl packages to generate the Q* classes? Or will the query-jpa and query-dsl:3.6.3:jpa packages correctly generate the Q* classes for hibernate-managed entities?

    The reason I ask is that this readme (https://github.com/querydsl/querydsl/tree/master/querydsl-jpa) implies that hibernate-managed entities should use a different annotation processor to generate the Q* classes.

    ReplyDelete