Generate Code
Code Generation
Similar to JPA2.0 Criteria, QueryDsl, Fluent MyBatis, etc., Jimmer uses strongly typed DSLs to catch errors at compile-time rather than runtime.
So some additional code needs to be generated at compile-time based on user-defined entities:
- Java users use Annotation Processor
- Kotlin users use KSP
- Java (Maven)
- Java (Gradle)
- Kotlin (Gradle.kts)
- Java (Gradle Plugin)
- Kotlin (Gradle Plugin)
...other code omitted...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.babyfish.jimmer</groupId>
<artifactId>jimmer-apt</artifactId>
<version>${jimmer.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
...other code omitted...
dependencies {
...other dependencies omitted...
annotationProcessor "org.babyfish.jimmer:jimmer-apt:${jimmerVersion}"
}
plugins {
// Add KSP plugin
id("com.google.devtools.ksp") version "1.7.10-1.0.6"
...other plugins omitted...
}
dependencies {
// Apply Jimmer's KSP code generator
ksp("org.babyfish.jimmer:jimmer-ksp:${jimmerVersion}")
...other dependencies omitted...
}
// Add generated code to compile path.
// Gradle build works without this, but IntelliJ won't find generated code.
kotlin {
sourceSets.main {
kotlin.srcDir("build/generated/ksp/main/kotlin")
}
}
plugins {
// Starting from Gradle 7.0, you can use "latest.release" instead of a specific version number to represent the use of the latest version.
// You can also use the '+' character to indicate matching the latest version number starting from the '+' character.
id "tech.argonariod.gradle-plugin-jimmer" version "latest.release"
...other plugins omitted...
}
jimmer {
// Set the Jimmer dependency version, where you can also use version range expressions such as "latest.release" or "0.+"
version = "${jimmerVersion}"
}
plugins {
// Starting from Gradle 7.0, you can use "latest.release" instead of a specific version number to represent the use of the latest version.
id("tech.argonariod.gradle-plugin-jimmer") version "latest.release"
// You can also use the '+' character to indicate matching the latest version number starting from the '+' character.
// Add KSP plugin
id("com.google.devtools.ksp") version "1.7.10+"
...other plugins omitted...
}
jimmer {
// Set the Jimmer dependency version, where you can also use version range expressions such as "latest.release" or "0.+"
version = "${jimmerVersion}"
}
- The first three: Standard configurations
- The last two: Community-provided Gradle plugin for further simplifying configurations
KSP only supports gradle, It has been proven that KSP's third-party Maven plug-in support cannot keep up with the version iteration of 'kotlin/KSP' itself, and often encounters many problems during the upgrade process.
Eventually, Jimmer dropped Maven support for Kotlin and asked Kotlin developers to use Gradle.
After this configuration, running Maven or Gradle will generate additional source code based on user-defined entities.
The above only applies to simple projects without separation.
For real projects with separate entity definition, generator (annotation processor/ksp) must be configured in the project that defines entity types.
Jimmer data types require one of:
@Immutable
@Entity
@MappedSuperclass
@Embeddable
The first is ORM-agnostic, the others are ORM-related.
If entities use the ORM annotations (eg: @Entity), the generated code requires jimmer-sql
while entity code itself only needs jimmer-core
:
- Maven
- Java (Gradle Plugin)
- Kotlin (Gradle Plugin)
- Java (Gradle)
- Kotlin (Gradle.kts)
...other code omitted...
<dependencies>
<!-- User entity code -->
<dependency>
<groupId>org.babyfish.jimmer</groupId>
<artifactId>jimmer-core</artifactId>
<version>${jimmer.version}</version>
</dependency>
<!-- Generated code -->
<dependency>
<groupId>org.babyfish.jimmer</groupId>
<artifactId>jimmer-sql</artifactId>
<version>${jimmer.version}</version>
<!-- Imported by other projects -->
<scope>provided</scope>
</dependency>
...other dependencies omitted...
</dependencies>
...other code omitted...
jimmer {
// Ensure that jimmer-sql is only depended upon during code generation and compilation.
ormCompileOnly = true
...other configurations omitted...
}
...other code omitted...
jimmer {
// Ensure that jimmer-sql-kotlin is only depended upon during code generation and compilation.
ormCompileOnly = true
...other configurations omitted...
}
...other code omitted...
...other code omitted...
dependencies {
...other dependencies omitted...
// User entity code
implementation "org.babyfish.jimmer:jimmer-core:${jimmerVersion}"
// Generated code
compileOnly "org.babyfish.jimmer:jimmer-sql:${jimmerVersion}"
}
...other code omitted...
...other code omitted...
dependencies {
...other dependencies omitted...
// User entity code
implementation("org.babyfish.jimmer:jimmer-core:${jimmerVersion}")
// Generated code
compileOnly("org.babyfish.jimmer:jimmer-sql:${jimmerVersion}")
}
...other code omitted...
Verify Successful Generation
If generation succeeded, developers should see:
Java | Kotlin |
---|---|
Screenshots are from Gradle project.
For Maven, top level directory is target instead of build.
Normally IDE marks generated code directories with icon.
But sometimes IntelliJ fails to do so, preventing use of generated code.
In this case, right-click on directory, choose Mark Directory As
-> Generated Sources Root
.
Generated code includes:
Java | Kotlin | Description |
---|---|---|
XXXDraft.java | XXXDraft.kt | Mutable proxy interface for immutable object, object implementation, and methods to create and "modify" objects |
XXXProps.java | XXXProps.kt | Typed SQL DSL |
XXXTable.java | ||
XXXTableEx.java | ||
XXXFetcher.java | XXXFetcher.kt | Object fetcher DSL defining shape of complex query results |