Booster #3: QueryDSL

Top 3 JPA productivity boosters for Java EE developers – QueryDSL

Matti Tahvonen
Booster image via Shutterstock

There are a lot of ways to be inefficient writing Java EE applications. But there’s three ways to enhance your JPA productivity, the last of which Matti Tahvonen lays out in the final part of this series: QueryDSL.

Spring Data and its CDI counterpart, DeltaSpike Data, are wonderful tools. They give you a huge productivity boost, especially when starting your project, and they don’t get in your way when you need to create something more complex with lower level APIs.

But their coolest feature, auto-generated queries based on method naming, and JPQL/SQL queries have some downsides. Your method names may easily become really long and you cannot add line breaks to method names. And, like if you‘d go with query languages, even with good tooling, there may be issues that you cannot spot that easily during development.

QueryDSL is a library to easily build queries with well typed Java API. Its awesomeness is based on helper classes that are automatically generated based on your entity classes. Autocomplete by IDE and strong typing makes it really easy to build queries that work with the first run, unlike most SQL or JPQL queries that I write. QueryDSL actually supports several backends, but its JPA support is naturally the thing we want to use here.

Both Spring Data and DeltaSpike Data module support using QueryDSL to write custom queries. So instead as a replacement for either of them, you should think of it as a complementary tool that you can turn to when the “repository generators” don’t feel that handy anymore. And you can think it as a more developer friendly way to programmatically express your queries, rather than to building them with somewhat tricky JPA Criteria API.

Personally, when simple method name based don’t feel adequate anymore, I would choose JPQL instead of Criteria API, but QueryDSL definitely turns the competition back to programmatic query definition.

Check out the example project using QueryDSL

To get started with QueryDSL, you’ll need to set up the annotation processor to create the helper classes. An easy way to do this is to add following maven plugin to your project:

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <id>querydsl</id>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/querydsl</outputDirectory>
                            <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>com.mysema.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>3.6.1</version>
                    </dependency>
                </dependencies>
            </plugin>

At runtime you’ll need following dependencies:

<dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-core</artifactId>
        <version>3.6.1</version>
    </dependency>
    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-jpa</artifactId>
        <version>3.6.1</version>
    </dependency>

Using QueryDSL as a complement to both repository generators is pretty easy, but Spring Data has bit a deeper integration. With its  findAll(Predicate predicate, Pageable pageable) method you can get straight to defining the predicate for your queries and use standard Spring Data sorting and paging APIs together with QueryDSL based queries. 

SEE ALSO: JPA productivity booster #1: Spring Data

The use case from this article could be written using a combination of Spring Data and QueryDSL like this:

    public List<Contact> findPaged(Invoicer invoicer, String filter,
            int firstResult, int maxResults) {
        return repository.findAll(
                QContact.contact.name.startsWithIgnoreCase(filter)
                .and(QContact.contact.invoicer.eq(invoicer)),
                new PageRequest(firstResult / maxResults, maxResults)
        ).getContent();
    }

Summary of all helper libraries 

I’m pretty happy I did my journey to investigate various JPA helper libraries for Java EE apps. I already knew that Spring Data was a super cool beast when it comes to kickstarting data centric applications, but I hadn’t realised it was so easy to use it in an otherwise standard Java EE environment as well.

I also found that DeltaSpike Data is a really viable alternative for the same use case. And it also has a cool “query by example” feature that you can’t find in Spring Data. If I had to choose between them I’d probably flip a coin or decide based on the team’s existing experience.

I also finally really tried to use QueryDSL. I had read a couple of articles about it and was already pretty convinced about its usefulness, but had never really tried it. Setting up the build script to automatically generate the query helpers classes is a small inconvenience, if you compare it to the productivity boost you get from it. With it you can say “bye bye” to nasty typos in SQL or JPQL queries. You should definitely check out this library, if you have lots of complex queries in your application. It also works well as a complement to both the “repository libraries”.

SEE ALSO: JPA productivity booster #2: DeltaSpike Data

I hope you can learn from my experiences. To get hands on quickly with any of these tools, check out my simple full stack phone book CRUD example on GitHub, which has three different facades to your database, implemented with the best JPA productivity boosters.

Author
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies.

Comments
comments powered by Disqus