Search code examples
springpluginskotlinquerydsl

How to user QueryDSL and generate file in Kotlin


I use the below maven pom.xml file and can't generate the querydsl file.

I have found a questrion:Kotlin-Kapt Annotation Processor not working with maven

I want to generate jpa querydsl files from kotlin entity classes.

There is a very good examples online of how to generate the dsl files using gradle https://github.com/JetBrains/kotlin-examples/blob/master/gradle/kotlin-querydsl/build.gradle.

However I have tried to implement this in maven and have had no luck. My current pom is below. Does anybody know what the issue might be? Thanks in advance.

It use querydsl3 and I use 4

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>cn.techcave.chat</groupId>
	<artifactId>jpa</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>jpa</name>
	<description>Kotlin Demo project for Spring Boot JPA</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<kotlin.version>1.2.10</kotlin.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-hal-browser</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jetbrains.kotlin</groupId>
			<artifactId>kotlin-stdlib-jdk8</artifactId>
			<version>${kotlin.version}</version>
		</dependency>
		<dependency>
			<groupId>org.jetbrains.kotlin</groupId>
			<artifactId>kotlin-reflect</artifactId>
			<version>${kotlin.version}</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--swagger 2-->
		<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.8.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.8.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.springfox/springfox-data-rest -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-data-rest</artifactId>
			<version>2.8.0</version>
		</dependency>

		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-apt</artifactId>
			<version>4.1.4</version>
		</dependency>
		<dependency>
			<groupId>com.querydsl</groupId>
			<artifactId>querydsl-jpa</artifactId>
			<version>4.1.4</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.xml.bind</groupId>
			<artifactId>jaxb-api</artifactId>
			<version>2.3.0</version>
			<!--<scope>test</scope>-->
		</dependency>
	</dependencies>

	<build>
		<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
		<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<artifactId>kotlin-maven-plugin</artifactId>
				<groupId>org.jetbrains.kotlin</groupId>
				<version>${kotlin.version}</version>
				<configuration>
					<compilerPlugins>
						<plugin>spring</plugin>
					</compilerPlugins>
					<jvmTarget>1.8</jvmTarget>
				</configuration>
				<executions>
                    <execution>
                        <id>kapt</id>
                        <goals>
                            <goal>kapt</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>/src/main/kotlin</sourceDir>
                                <!--<sourceDir>${project.basedir}/src/main/java</sourceDir>-->
                            </sourceDirs>
                            <annotationProcessorPaths>
                                <annotationProcessorPath>
                                    <groupId>com.querydsl</groupId>
                                    <artifactId>querydsl-apt</artifactId>
                                    <version>4.1.4</version>
                                    <classifier>jpa</classifier>
                                </annotationProcessorPath>
                            </annotationProcessorPaths>
                            <!--<annotationProcessors>-->
                                <!--<outputDirectory>target/generated-sources/java</outputDirectory>-->
                                <!--<processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor>-->
                            <!--</annotationProcessors>-->
                        </configuration>
                    </execution>
					<execution>
						<id>compile</id>
						<phase>compile</phase>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
					<execution>
						<id>test-compile</id>
						<phase>test-compile</phase>
						<goals>
							<goal>test-compile</goal>
						</goals>
					</execution>
				</executions>
				<dependencies>
					<dependency>
						<groupId>org.jetbrains.kotlin</groupId>
						<artifactId>kotlin-maven-allopen</artifactId>
						<version>${kotlin.version}</version>
					</dependency>
				</dependencies>
			</plugin>
			<!--<plugin>-->
				<!--<groupId>com.mysema.maven</groupId>-->
				<!--<artifactId>apt-maven-plugin</artifactId>-->
				<!--<version>1.1.3</version>-->
				<!--<executions>-->
					<!--<execution>-->
						<!--<goals>-->
							<!--<goal>process</goal>-->
						<!--</goals>-->
						<!--<configuration>-->
							<!--<outputDirectory>target/generated-sources/java</outputDirectory>-->
							<!--<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>-->
						<!--</configuration>-->
					<!--</execution>-->
				<!--</executions>-->
			<!--</plugin>-->
		</plugins>
	</build>


</project>

thanks


Solution

  • I ran into this today. There are a few issues in play:

    1. The "kapt" plugin hooks the "compile" phase, so any compiler plugins (no-arg/JPA/Spring) that you have in there will override it. You can comment out the <jpa> line in your <compilerPlugins> block and it should spit out your Q classes, but then you lose your entity classes' no-arg constructors.
    2. Even if you get that working, prior to Kotlin version 1.2.20, there is a bug that prevents subsequent compilations from running due to kapt bugging out when it encounters generated output files that already exist. This is fixed in 1.2.20.
    3. It is possible to move the <compilerPlugins> block from the top <plugin>-level down to the "compile" execution, but this effectively caused the plugins to be ignored. My project would compile, but then fail at runtime due to the Spring config classes being treated as final and my entity classes lacking no-arg default constructors.

    The solution that I found was to move the kotlin-maven-plugin's <compile> execution from the compile phase to the process-sources phase, e.g.:

    <build>       
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    
    
        <plugins>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <configuration>
                    <jvmTarget>1.8</jvmTarget>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                    </compilerPlugins>
                </configuration>
    
                <executions>
    
                    <execution>
                        <id>compile</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
    
                    <execution>
                        <id>kapt</id>
                        <goals>
                            <goal>kapt</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>src/main/kotlin</sourceDir>
                            </sourceDirs>
                            <annotationProcessorPaths>
                                <annotationProcessorPath>
                                    <groupId>com.querydsl</groupId>
                                    <artifactId>querydsl-apt</artifactId>
                                    <version>${querydsl.version}</version>
                                    <classifier>jpa</classifier>
                                </annotationProcessorPath>
                            </annotationProcessorPaths>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>src/test/kotlin</sourceDir>
                                <sourceDir>target/generated-sources/kapt/test</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    

    This worked for me on a Spring Boot project with Spring-Data-JPA and Spring-Data-REST.