Auf Arbeit sind wir gerade dabei, sämtliche Anwendungen auf Spring Boot 3 zu aktualisieren. Die meisten Anpassungen dafür sind trivial, QueryDSL hat mir aber etwas Kopfzerbrechen bereitet, da die Dokumentation noch auf einem alten Stand ist.

Konfiguration vor Spring Boot 3

Bislang wurde QueryDSL wie folgt eingebunden:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.7</version>
    </parent>

    <groupId>example</groupId>
    <artifactId>example</artifactId>
    <version>0.0.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
        </dependency>
    </dependencies>

</project>

Update auf Spring Boot 3

Die Umstellung auf Spring Boot 3 erfolgt durch Anpassung des Elternprojektes:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
    </parent>

Hibernate 6 / Jakarta EE Kompatibilität

Da Spring Boot 3 nun jedoch Hibernate 6 verwendet, das wiederum auf Jakarta EE basiert, werden mit dieser Konfiguration inkompatible Q-Klassen erstellt (siehe Support Hibernate 6.x.x #3436). Das lässt sich schnell beheben, indem spezielle Jakarta-Pakete verwendet werden. Durch die Umstellung muss auch explizit die Versionsnummer bei den Paketen mit angegeben werden:

    <dependencies>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
            <classifier>jakarta</classifier>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
            <classifier>jakarta</classifier>
        </dependency>
    </dependencies>

Fehler beim Erzeugen der Q-Klassen

Nach dieser Anpassung werden die Q-Klassen aber sowohl unter target/generated-sources/java als auch unter target/generated-sources/annotations erzeugt.

Schuld daran ist eine Service Deklaration, die zwar in den Jakarta-Paketen nicht jedoch in den Standard-Paketen enthalten ist (siehe JPAAnnotationProcessor with classifier jakarta fails with "Attempt to recreate a file for type" #3431). Das Problem kann ganz einfach gelöst werden, indem das nun überflüssige apt-maven-plugin entfernt wird.

Komplette Konfiguration

Die Komplette QueryDSL-Konfiguration für Spring Boot 3 sieht nun wie folgt aus:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.0</version>
    </parent>

    <groupId>example</groupId>
    <artifactId>example</artifactId>
    <version>0.0.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
            <classifier>jakarta</classifier>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
            <classifier>jakarta</classifier>
        </dependency>
    </dependencies>

</project>