diff --git a/tooling/hibernate-gradle-plugin/README.adoc b/tooling/hibernate-gradle-plugin/README.adoc index 0fcb6e84e8..57a45757e1 100644 --- a/tooling/hibernate-gradle-plugin/README.adoc +++ b/tooling/hibernate-gradle-plugin/README.adoc @@ -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 +* <> +* <> +* <> -* 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... \ No newline at end of file diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java index a2ff441fc8..cf52ee3f42 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java @@ -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 { } 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 { modelCompileTask.setSourceCompatibility( languageCompileTask.getSourceCompatibility() ); modelCompileTask.setTargetCompatibility( languageCompileTask.getTargetCompatibility() ); - genTask.injectJavaVersion( languageCompileTask.getSourceCompatibility() ); modelCompileTask.finalizedBy( modelCompileTask ); } ); @@ -124,9 +129,17 @@ public class HibernateOrmPlugin implements Plugin { 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 ); } ); } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java index 38cb107b9f..f235a9c8d1 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmSpec.java @@ -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 useSameVersion; - private final Project project; - private final Property sourceSetProperty; + private final Property sourceSet; private final Provider enhancementDslAccess; private final Provider 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 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 ); } /** diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationSpec.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationSpec.java index 9a2ba7c1cb..60a6530189 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationSpec.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationSpec.java @@ -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 applyGeneratedAnnotation; private final Project project; - private final SetProperty suppressions; + private final DirectoryProperty generationOutputDirectory; private final DirectoryProperty compileOutputDirectory; - private final Provider targetJavaVersionAccess; + private final Property applyGeneratedAnnotation; + private final SetProperty 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 getTargetJavaVersionAccess() { - return targetJavaVersionAccess; + suppressions = project.getObjects().setProperty( String.class ); + suppressions.convention( Arrays.asList( "raw", "deprecation" ) ); } public Property getApplyGeneratedAnnotation() { diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationTask.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationTask.java index 7ccdf12a64..83e1926e71 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationTask.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/JpaMetamodelGenerationTask.java @@ -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 sourceSetProperty; + private final DirectoryProperty generationOutputDirectory; - private final Property sourceSetProperty; private final Property applyGeneratedAnnotation; private final SetProperty suppressions; - private final Property 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 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 getSuppressions() { return suppressions; } - - @Override - public Provider getTargetJavaVersionAccess() { - return javaVersion; - } }; } @@ -187,6 +171,7 @@ public class JpaMetamodelGenerationTask extends DefaultTask { } public static void apply(HibernateOrmSpec pluginDsl, Project project) { + // todo : implement it } } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/GenerationOptions.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/GenerationOptions.java index 7f26bb2ad0..22acf56bda 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/GenerationOptions.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/GenerationOptions.java @@ -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 getGenerationDirectory(); Provider getApplyGeneratedAnnotation(); SetProperty getSuppressions(); - Provider getTargetJavaVersionAccess(); } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/JpaStaticMetamodelGenerator.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/JpaStaticMetamodelGenerator.java index 4165b2966c..bcd7b74559 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/JpaStaticMetamodelGenerator.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/JpaStaticMetamodelGenerator.java @@ -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() ); diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/MetamodelClass.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/MetamodelClass.java index c3ddce2e38..4873d406fc 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/MetamodelClass.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/metamodel/model/MetamodelClass.java @@ -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" diff --git a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle index 8eb0381d47..20bc5d3281 100644 --- a/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle +++ b/tooling/hibernate-gradle-plugin/src/test/resources/projects/simple/build.gradle @@ -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' }