HHH-15314 - Hibernate Gradle plugin is not working for Kotlin projects

This commit is contained in:
Steve Ebersole 2022-06-08 17:32:52 -05:00
parent fd7cca8fdc
commit 180089b542
9 changed files with 128 additions and 88 deletions

View File

@ -5,47 +5,114 @@ A Gradle plugin for introducing Hibernate tasks and capabilities into a build.
== Set up
```
[source,groovy]
----
plugins {
id 'org.hibernate.orm' version='X'
id 'org.hibernate.orm'
}
// HibernateOrmSpec
hibernate {
...
}
```
----
== Bytecode Enhancement
The plugin can perform build-time enhancement of the domain classes. This is controlled
by the `enhancement` portion of the `hibernate` extension:
```
hibernate {
// EnhancementSpec
enhancement {
// available options - all default to false
lazyInitialization( true )
}
}
```
== DSL
The `hibernate` DSL extension is the main entry into configuring the plugin
```
[source,groovy]
----
hibernate {
}
```
----
At this time, there is no configuration at this level.
It defines configuration options:
== Capa
useSameVersion:: Specifies whether to have the plugin inject an `implementation` dependency on `hibernate-core`, implicitly using
the same version as the plugin. The default is true. If you'd prefer to use a different version, set this to false and define
the dependency on `hibernate-core` as you normally would.
sourceSet:: The source-set containing the project's domain model. Only one source-set is supported, although all languages (Java, Kotlin, etc)
within that source-set are considered.
== Tasks
It additionally defines 3 nested DSL extensions related to:
== Additional Resources
* <<enhance>>
* <<jpa-metamodel>>
* <<hbm-xml>>
* https://plugins.gradle.org/plugin/org.hibernate.orm
[[enhance]]
== Bytecode Enhancement
The plugin can perform build-time enhancement of the domain classes. This is controlled
by the `enhancement` portion of the `hibernate` DSL extension.
To enable enhancement, reference the DSL extension:
[source,groovy]
----
hibernate {
enhancement
}
----
Enhancement has a few options to control what enhancements take place. All the options default to `false`:
[source,groovy]
----
hibernate {
enhancement {
lazyInitialization = true
dirtyTracking = true
associationManagement = true
extendedEnhancement = false
}
}
----
[[jpa-metamodel]]
== JPA Static Metamodel generation
The plugin can also generate the JPA static metamodel classes based on the application's domain model. To enable
the generation, simply refer to the DSL extension:
[source,groovy]
----
hibernate {
jpaMetamodel
}
----
The generation accepts a number of options:
[source,groovy]
----
hibernate {
jpaMetamodel {
// directory where the generated metamodel source files should be written
// - defaults to `${buildDir}/generated/sources/jpaMetamodel
generationOutputDirectory = "some/other/dir"
// directory where the compiled generated metamodel classes should be written
// - defaults to `${buildDir}/classes/java/jpaMetamodel
compileOutputDirectory = "special/classes/dir"
// should the `jakarta.annotation.Generated` annotation be applied?
// - defaults to true
applyGeneratedAnnotation = true
// error suppressions to be added to the generated source files
// - default is ["raw", "deprecation"]
suppressions = ...
}
}
----
[[hbm-xml]]
== Legacy `hbm.xml` Transformation
Coming soon...

View File

@ -10,7 +10,9 @@ import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JvmEcosystemPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
@ -99,8 +101,12 @@ public class HibernateOrmPlugin implements Plugin<Project> {
}
genTask.injectSourceSet( ormDsl.getSourceSet() );
genTask.getGenerationOutputDirectory().set( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() );
genTask.getApplyGeneratedAnnotation().convention( ormDsl.getJpaMetamodel().getApplyGeneratedAnnotation() );
genTask.getSuppressions().convention( ormDsl.getJpaMetamodel().getSuppressions() );
final JavaCompile modelCompileTask = modelCompileTaskRef.get();
final SourceSet sourceSet = ormDsl.getSourceSet().get();
@ -112,7 +118,6 @@ public class HibernateOrmPlugin implements Plugin<Project> {
modelCompileTask.setSourceCompatibility( languageCompileTask.getSourceCompatibility() );
modelCompileTask.setTargetCompatibility( languageCompileTask.getTargetCompatibility() );
genTask.injectJavaVersion( languageCompileTask.getSourceCompatibility() );
modelCompileTask.finalizedBy( modelCompileTask );
} );
@ -124,9 +129,17 @@ public class HibernateOrmPlugin implements Plugin<Project> {
modelCompileTask.source( project.files( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() ) );
modelCompileTask.getDestinationDirectory().set( ormDsl.getJpaMetamodel().getCompileOutputDirectory() );
modelCompileTask.setClasspath(
project.getConfigurations().getByName( "runtimeClasspath" ).plus( sourceSet.getRuntimeClasspath() )
FileCollection metamodelCompileClasspath = project.getConfigurations().getByName( "runtimeClasspath" )
.plus( sourceSet.getCompileClasspath() )
.plus( sourceSet.getRuntimeClasspath() );
if ( ormDsl.getJpaMetamodel().getApplyGeneratedAnnotation().getOrElse( true ) ) {
final Dependency jakartaAnnotationsDep = project.getDependencies().create( "jakarta.annotation:jakarta.annotation-api:2.0.0" );
metamodelCompileClasspath = metamodelCompileClasspath.plus(
project.getConfigurations().detachedConfiguration( jakartaAnnotationsDep )
);
}
modelCompileTask.setClasspath( metamodelCompileClasspath );
} );
}

View File

@ -28,12 +28,13 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
public static final String DSL_NAME = HIBERNATE;
private final Project project;
private EnhancementSpec enhancementDsl;
private JpaMetamodelGenerationSpec jpaMetamodelDsl;
private final Property<Boolean> useSameVersion;
private final Project project;
private final Property<SourceSet> sourceSetProperty;
private final Property<SourceSet> sourceSet;
private final Provider<EnhancementSpec> enhancementDslAccess;
private final Provider<JpaMetamodelGenerationSpec> jpaMetamodelDslAccess;
@ -46,8 +47,8 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
useSameVersion = project.getObjects().property( Boolean.class );
useSameVersion.convention( true );
sourceSetProperty = project.getObjects().property( SourceSet.class );
sourceSetProperty.convention( mainSourceSet( project ) );
sourceSet = project.getObjects().property( SourceSet.class );
sourceSet.convention( mainSourceSet( project ) );
enhancementDslAccess = project.provider( () -> enhancementDsl );
jpaMetamodelDslAccess = project.provider( () -> jpaMetamodelDsl );
@ -93,7 +94,7 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
* The source-set containing the domain model. Defaults to the `main` source-set
*/
public Property<SourceSet> getSourceSet() {
return sourceSetProperty;
return sourceSet;
}
/**
@ -107,7 +108,7 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
* @see #getSourceSet()
*/
public void setSourceSet(SourceSet sourceSet) {
sourceSetProperty.set( sourceSet );
this.sourceSet.set( sourceSet );
}
/**

View File

@ -9,15 +9,10 @@ package org.hibernate.orm.tooling.gradle.metamodel;
import java.util.Arrays;
import javax.inject.Inject;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.compile.JavaCompile;
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
@ -28,24 +23,18 @@ public class JpaMetamodelGenerationSpec {
public static final String JPA_METAMODEL = "jpaMetamodel";
public static final String DSL_NAME = JPA_METAMODEL;
private final Property<Boolean> applyGeneratedAnnotation;
private final Project project;
private final SetProperty<String> suppressions;
private final DirectoryProperty generationOutputDirectory;
private final DirectoryProperty compileOutputDirectory;
private final Provider<JavaVersion> targetJavaVersionAccess;
private final Property<Boolean> applyGeneratedAnnotation;
private final SetProperty<String> suppressions;
@Inject
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
this.project = project;
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
applyGeneratedAnnotation.convention( true );
suppressions = project.getObjects().setProperty( String.class );
suppressions.convention( Arrays.asList( "raw", "deprecation" ) );
generationOutputDirectory = project.getObjects().directoryProperty();
generationOutputDirectory.convention(
project.getLayout().getBuildDirectory().dir( "generated/sources/" + JPA_METAMODEL )
@ -56,17 +45,11 @@ public class JpaMetamodelGenerationSpec {
project.getLayout().getBuildDirectory().dir( "classes/java/" + JPA_METAMODEL )
);
targetJavaVersionAccess = project.provider( () -> {
final SourceSetContainer sourceSets = project.getExtensions().getByType( SourceSetContainer.class );
final SourceSet sourceSet = sourceSets.getByName( SourceSet.MAIN_SOURCE_SET_NAME );
final String compileTaskName = sourceSet.getCompileJavaTaskName();
final JavaCompile compileTask = (JavaCompile) project.getTasks().getByName( compileTaskName );
return JavaVersion.toVersion( compileTask.getTargetCompatibility() );
} );
}
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
applyGeneratedAnnotation.convention( true );
public Provider<JavaVersion> getTargetJavaVersionAccess() {
return targetJavaVersionAccess;
suppressions = project.getObjects().setProperty( String.class );
suppressions.convention( Arrays.asList( "raw", "deprecation" ) );
}
public Property<Boolean> getApplyGeneratedAnnotation() {

View File

@ -9,12 +9,10 @@ package org.hibernate.orm.tooling.gradle.metamodel;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Properties;
import javax.inject.Inject;
import org.gradle.api.DefaultTask;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.file.ConfigurableFileTree;
import org.gradle.api.file.Directory;
@ -50,13 +48,13 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
public static final String GEN_TASK_NAME = "generateJpaMetamodel";
public static final String COMPILE_META_TASK_NAME = "compileJpaMetamodel";
private final Property<SourceSet> sourceSetProperty;
private final DirectoryProperty generationOutputDirectory;
private final Property<SourceSet> sourceSetProperty;
private final Property<Boolean> applyGeneratedAnnotation;
private final SetProperty<String> suppressions;
private final Property<JavaVersion> javaVersion;
@Inject
@ -69,23 +67,14 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
generationOutputDirectory = getProject().getObjects().directoryProperty();
applyGeneratedAnnotation = getProject().getObjects().property( Boolean.class );
applyGeneratedAnnotation.convention( true );
suppressions = getProject().getObjects().setProperty( String.class );
suppressions.convention( Arrays.asList( "raw", "deprecation" ) );
javaVersion = getProject().getObjects().property( JavaVersion.class );
javaVersion.convention( JavaVersion.current() );
}
public void injectSourceSet(Provider<SourceSet> sourceSetAccess) {
sourceSetProperty.set( sourceSetAccess );
}
public void injectJavaVersion(Object version) {
javaVersion.set( JavaVersion.toVersion( version ) );
}
@OutputDirectory
public DirectoryProperty getGenerationOutputDirectory() {
return generationOutputDirectory;
@ -149,11 +138,6 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
public SetProperty<String> getSuppressions() {
return suppressions;
}
@Override
public Provider<JavaVersion> getTargetJavaVersionAccess() {
return javaVersion;
}
};
}
@ -187,6 +171,7 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
}
public static void apply(HibernateOrmSpec pluginDsl, Project project) {
// todo : implement it
}
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.orm.tooling.gradle.metamodel.model;
import org.gradle.api.JavaVersion;
import org.gradle.api.file.Directory;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.SetProperty;
@ -18,5 +17,4 @@ public interface GenerationOptions {
Provider<Directory> getGenerationDirectory();
Provider<Boolean> getApplyGeneratedAnnotation();
SetProperty<String> getSuppressions();
Provider<JavaVersion> getTargetJavaVersionAccess();
}

View File

@ -66,13 +66,11 @@ public class JpaStaticMetamodelGenerator {
}
}
@SuppressWarnings( "unchecked" )
private void handleMappedClass(MappedSuperclass mappingDescriptor) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( mappingDescriptor );
handleManagedClass( metamodelClass, mappingDescriptor.getDeclaredPropertyIterator() );
}
@SuppressWarnings( "unchecked" )
private void handlePersistentClass(PersistentClass persistentClass) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( persistentClass );
handleManagedClass( metamodelClass, persistentClass.getDeclaredPropertyIterator() );

View File

@ -22,7 +22,6 @@ import java.util.Set;
import java.util.TreeSet;
import org.gradle.api.GradleException;
import org.gradle.api.JavaVersion;
import static java.lang.Character.LINE_SEPARATOR;
@ -112,14 +111,9 @@ public class MetamodelClass {
// first, the generated annotation
if ( options.getApplyGeneratedAnnotation().getOrElse( true ) ) {
final JavaVersion javaVersion = options.getTargetJavaVersionAccess().getOrElse( JavaVersion.current() );
final String qualifiedAnnotationName = javaVersion.isJava9Compatible()
? "javax.annotation.processing.Generated"
: "jakarta.annotation.Generated";
final String generatedAnnotationFragment = String.format(
Locale.ROOT,
"@%s( value=\"%s\", date=\"%s\", comments=\"%s\" )",
qualifiedAnnotationName,
"@jakarta.annotation.Generated( value=\"%s\", date=\"%s\", comments=\"%s\" )",
JpaStaticMetamodelGenerator.class.getName(),
nowFormatted,
"Generated by Hibernate ORM Gradle tooling"

View File

@ -20,6 +20,7 @@ repositories {
}
dependencies {
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final'
}