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

This commit is contained in:
Steve Ebersole 2022-06-08 16:28:15 -05:00
parent 76055475da
commit fd7cca8fdc
16 changed files with 637 additions and 412 deletions

View File

@ -13,12 +13,17 @@ import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.plugins.JvmEcosystemPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.compile.AbstractCompile;
import org.gradle.api.tasks.compile.JavaCompile;
import org.hibernate.orm.tooling.gradle.enhance.EnhancementHelper;
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask;
import static org.hibernate.orm.tooling.gradle.Helper.determineCompileSourceSetName;
import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.COMPILE_META_TASK_NAME;
import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.GEN_TASK_NAME;
/**
* Hibernate ORM Gradle plugin
@ -33,26 +38,29 @@ public class HibernateOrmPlugin implements Plugin<Project> {
final HibernateOrmSpec ormDsl = project.getExtensions().create( HibernateOrmSpec.DSL_NAME, HibernateOrmSpec.class, project );
prepareEnhancement( ormDsl, project );
prepareModelGen( ormDsl, project );
prepareHbmTransformation( ormDsl, project );
JpaMetamodelGenerationTask.apply( ormDsl, ormDsl.getSourceSetProperty().get(), project );
// project.getDependencies().add(
// "implementation",
// ormDsl.getHibernateVersionProperty().map( (ormVersion) -> Character.isDigit( ormVersion.charAt( 0 ) )
// ? "org.hibernate.orm:hibernate-core:" + ormVersion
// : null
// )
// );
//noinspection ConstantConditions
project.getDependencies().add(
"implementation",
ormDsl.getUseSameVersion().map( (use) -> use
? "org.hibernate.orm:hibernate-core:" + HibernateVersion.version
: null
)
);
}
private void prepareEnhancement(HibernateOrmSpec ormDsl, Project project) {
project.getGradle().getTaskGraph().whenReady( (graph) -> {
if ( !ormDsl.getSupportEnhancementProperty().get() ) {
if ( !ormDsl.isEnhancementEnabled() ) {
return;
}
graph.getAllTasks().forEach( (task) -> {
if ( task instanceof AbstractCompile ) {
final SourceSet sourceSetLocal = ormDsl.getSourceSetProperty().get();
final SourceSet sourceSetLocal = ormDsl.getSourceSet().get();
final String compiledSourceSetName = determineCompileSourceSetName( task.getName() );
if ( !sourceSetLocal.getName().equals( compiledSourceSetName ) ) {
@ -60,7 +68,7 @@ public class HibernateOrmPlugin implements Plugin<Project> {
}
final AbstractCompile compileTask = (AbstractCompile) task;
//noinspection Convert2Lambda
//noinspection Convert2Lambda,NullableProblems
task.doLast( new Action<>() {
@Override
public void execute(Task t) {
@ -70,10 +78,59 @@ public class HibernateOrmPlugin implements Plugin<Project> {
EnhancementHelper.enhance( classesDirectory, classLoader, ormDsl, project );
}
} );
task.finalizedBy( this );
}
} );
} );
}
private void prepareModelGen(HibernateOrmSpec ormDsl, Project project) {
final TaskProvider<JavaCompile> modelCompileTaskRef = project.getTasks().register( COMPILE_META_TASK_NAME, JavaCompile.class, (modelCompileTask) -> {
modelCompileTask.onlyIf( (t) -> ormDsl.isMetamodelGenerationEnabled() );
modelCompileTask.setGroup( HIBERNATE );
modelCompileTask.setDescription( "Compiles the JPA static metamodel generated by `" + GEN_TASK_NAME + "`" );
} );
project.getTasks().register( GEN_TASK_NAME, JpaMetamodelGenerationTask.class, (genTask) -> {
genTask.onlyIf( (t) -> ormDsl.isMetamodelGenerationEnabled() );
if ( !ormDsl.isMetamodelGenerationEnabled() ) {
return;
}
genTask.injectSourceSet( ormDsl.getSourceSet() );
genTask.getGenerationOutputDirectory().set( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() );
final JavaCompile modelCompileTask = modelCompileTaskRef.get();
final SourceSet sourceSet = ormDsl.getSourceSet().get();
sourceSet.getAllSource().minus( sourceSet.getAllSource() ).forEach( (dir) -> {
final String language = dir.getName();
final String languageCompileTaskName = sourceSet.getCompileTaskName( language );
final AbstractCompile languageCompileTask = (AbstractCompile) project.getTasks().getByName( languageCompileTaskName );
genTask.dependsOn( languageCompileTask );
modelCompileTask.setSourceCompatibility( languageCompileTask.getSourceCompatibility() );
modelCompileTask.setTargetCompatibility( languageCompileTask.getTargetCompatibility() );
genTask.injectJavaVersion( languageCompileTask.getSourceCompatibility() );
modelCompileTask.finalizedBy( modelCompileTask );
} );
genTask.dependsOn( sourceSet.getProcessResourcesTaskName() );
genTask.finalizedBy( modelCompileTask );
modelCompileTask.dependsOn( genTask );
modelCompileTask.source( project.files( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() ) );
modelCompileTask.getDestinationDirectory().set( ormDsl.getJpaMetamodel().getCompileOutputDirectory() );
modelCompileTask.setClasspath(
project.getConfigurations().getByName( "runtimeClasspath" ).plus( sourceSet.getRuntimeClasspath() )
);
} );
}
private void prepareHbmTransformation(HibernateOrmSpec ormDsl, Project project) {
}
}

View File

@ -14,6 +14,7 @@ import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.plugins.ExtensionContainer;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.hibernate.orm.tooling.gradle.enhance.EnhancementSpec;
@ -27,34 +28,29 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
public static final String DSL_NAME = HIBERNATE;
private final Property<String> hibernateVersionProperty;
private EnhancementSpec enhancementDsl;
private JpaMetamodelGenerationSpec jpaMetamodelDsl;
private final Property<Boolean> useSameVersion;
private final Project project;
private final Property<SourceSet> sourceSetProperty;
private final Property<Boolean> supportEnhancementProperty;
private final Property<Boolean> supportJpaMetamodelProperty;
private final EnhancementSpec enhancementDsl;
private final JpaMetamodelGenerationSpec jpaMetamodelDsl;
private final Provider<EnhancementSpec> enhancementDslAccess;
private final Provider<JpaMetamodelGenerationSpec> jpaMetamodelDslAccess;
@Inject
public HibernateOrmSpec(Project project) {
this.project = project;
hibernateVersionProperty = project.getObjects().property( String.class );
hibernateVersionProperty.convention( HibernateVersion.version );
useSameVersion = project.getObjects().property( Boolean.class );
useSameVersion.convention( true );
sourceSetProperty = project.getObjects().property( SourceSet.class );
sourceSetProperty.convention( mainSourceSet( project ) );
supportEnhancementProperty = project.getObjects().property( Boolean.class );
supportEnhancementProperty.convention( true );
supportJpaMetamodelProperty = project.getObjects().property( Boolean.class );
supportJpaMetamodelProperty.convention( true );
enhancementDsl = getExtensions().create( EnhancementSpec.DSL_NAME, EnhancementSpec.class, this, project );
jpaMetamodelDsl = getExtensions().create( JpaMetamodelGenerationSpec.DSL_NAME, JpaMetamodelGenerationSpec.class, this, project );
enhancementDslAccess = project.provider( () -> enhancementDsl );
jpaMetamodelDslAccess = project.provider( () -> jpaMetamodelDsl );
}
private static SourceSet mainSourceSet(Project project) {
@ -66,68 +62,126 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
return javaPluginExtension.getSourceSets().getByName( name );
}
public Property<String> getHibernateVersionProperty() {
return hibernateVersionProperty;
/**
* Should the plugin inject a dependency on the same version of `hibernate-core`
* as the version of this plugin? The dependency is added to the `implementation`
* {@link org.gradle.api.artifacts.Configuration}.
* <p>
* Defaults to {@code true}. If overriding and performing enhancement, be aware
* that Hibernate generally only supports using classes enhanced using matching
* versions between tooling and runtime. In other words, be careful.
*/
public Property<Boolean> getUseSameVersion() {
return useSameVersion;
}
public void hibernateVersion(String version) {
setHibernateVersion( version );
/**
* @see #getUseSameVersion()
*/
public void setUseSameVersion(boolean value) {
useSameVersion.set( value );
}
public void setHibernateVersion(String version) {
hibernateVersionProperty.set( version );
/**
* @see #getUseSameVersion()
*/
public void useSameVersion() {
useSameVersion.set( true );
}
public Property<SourceSet> getSourceSetProperty() {
/**
* The source-set containing the domain model. Defaults to the `main` source-set
*/
public Property<SourceSet> getSourceSet() {
return sourceSetProperty;
}
/**
* @see #getSourceSet()
*/
public void setSourceSet(String name) {
setSourceSet( resolveSourceSet( name, project ) );
}
/**
* @see #getSourceSet()
*/
public void setSourceSet(SourceSet sourceSet) {
sourceSetProperty.set( sourceSet );
}
/**
* @see #getSourceSet()
*/
public void sourceSet(String name) {
setSourceSet( resolveSourceSet( name, project ) );
}
/**
* @see #getSourceSet()
*/
public void sourceSet(SourceSet sourceSet) {
setSourceSet( sourceSet );
}
public Property<Boolean> getSupportEnhancementProperty() {
return supportEnhancementProperty;
}
/**
* DSL extension for configuring bytecode enhancement. Also acts as the trigger for
* opting into bytecode enhancement
*/
public EnhancementSpec getEnhancement() {
if ( enhancementDsl == null ) {
enhancementDsl = getExtensions().create( EnhancementSpec.DSL_NAME, EnhancementSpec.class, this, project );
}
public void disableEnhancement() {
supportEnhancementProperty.set( false );
}
public Property<Boolean> getSupportJpaMetamodelProperty() {
return supportJpaMetamodelProperty;
}
public void disableJpaMetamodel() {
supportJpaMetamodelProperty.set( false );
}
public EnhancementSpec getEnhancementSpec() {
return enhancementDsl;
}
public void enhancement(Action<EnhancementSpec> action) {
action.execute( enhancementDsl );
/**
* Provider access to {@link #getEnhancement()}
*/
public Provider<EnhancementSpec> getEnhancementDslAccess() {
return enhancementDslAccess;
}
public JpaMetamodelGenerationSpec getJpaMetamodelSpec() {
public boolean isEnhancementEnabled() {
return enhancementDsl != null;
}
/**
* @see #getEnhancement()
*/
public void enhancement(Action<EnhancementSpec> action) {
action.execute( getEnhancement() );
}
/**
* DSL extension for configuring JPA static metamodel generation. Also acts as the trigger for
* opting into the generation
*/
public JpaMetamodelGenerationSpec getJpaMetamodel() {
if ( jpaMetamodelDsl == null ) {
jpaMetamodelDsl = getExtensions().create( JpaMetamodelGenerationSpec.DSL_NAME, JpaMetamodelGenerationSpec.class, this, project );
}
return jpaMetamodelDsl;
}
/**
* Provider access to {@link #getJpaMetamodel()}
*/
public Provider<JpaMetamodelGenerationSpec> getJpaMetamodelDslAccess() {
return jpaMetamodelDslAccess;
}
public boolean isMetamodelGenerationEnabled() {
return jpaMetamodelDsl != null;
}
/**
* @see #getJpaMetamodel()
*/
public void jpaMetamodel(Action<JpaMetamodelGenerationSpec>action) {
action.execute( jpaMetamodelDsl );
action.execute( getJpaMetamodel() );
}
@Override

View File

@ -89,7 +89,7 @@ public class EnhancementHelper {
}
public static Enhancer generateEnhancer(ClassLoader classLoader, HibernateOrmSpec ormDsl) {
final EnhancementSpec enhancementDsl = ormDsl.getEnhancementSpec();
final EnhancementSpec enhancementDsl = ormDsl.getEnhancement();
final EnhancementContext enhancementContext = new DefaultEnhancementContext() {
@Override

View File

@ -12,11 +12,11 @@ import javax.inject.Inject;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.plugins.JavaPluginConvention;
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;
@ -37,7 +37,6 @@ public class JpaMetamodelGenerationSpec {
private final Provider<JavaVersion> targetJavaVersionAccess;
@Inject
@SuppressWarnings( "UnstableApiUsage" )
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
this.project = project;
@ -57,16 +56,13 @@ public class JpaMetamodelGenerationSpec {
project.getLayout().getBuildDirectory().dir( "classes/java/" + JPA_METAMODEL )
);
targetJavaVersionAccess = project.provider(
() -> {
final JavaPluginConvention javaPluginConvention = project.getConvention().findPlugin( JavaPluginConvention.class );
assert javaPluginConvention != null;
final SourceSet sourceSet = javaPluginConvention.getSourceSets().getByName( SourceSet.MAIN_SOURCE_SET_NAME );
final String compileTaskName = sourceSet.getCompileJavaTaskName();
final JavaCompile compileTask = (JavaCompile) project.getTasks().getByName( compileTaskName );
return JavaVersion.toVersion( compileTask.getTargetCompatibility() );
}
);
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() );
} );
}
public Provider<JavaVersion> getTargetJavaVersionAccess() {

View File

@ -8,42 +8,33 @@ package org.hibernate.orm.tooling.gradle.metamodel;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Properties;
import javax.inject.Inject;
import javax.sql.DataSource;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.JavaVersion;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.ConfigurableFileTree;
import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.SkipWhenEmpty;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetOutput;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.compile.JavaCompile;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.hibernate.orm.tooling.gradle.Helper;
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
import org.hibernate.orm.tooling.gradle.metamodel.model.GenerationOptions;
import org.hibernate.orm.tooling.gradle.metamodel.model.JpaStaticMetamodelGenerator;
import org.hibernate.orm.tooling.gradle.metamodel.model.MetamodelClass;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.persistence.spi.PersistenceUnitTransactionType;
import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
@ -56,86 +47,114 @@ import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
* classes based on annotations. This task accounts for both classes and XML mappings
*/
public class JpaMetamodelGenerationTask extends DefaultTask {
public static final String DSL_NAME = "generateJpaMetamodel";
public static final String COMPILE_DSL_NAME = "compileJpaMetamodel";
public static final String GEN_TASK_NAME = "generateJpaMetamodel";
public static final String COMPILE_META_TASK_NAME = "compileJpaMetamodel";
private final DirectoryProperty generationOutputDirectory;
private final Property<SourceSet> sourceSetProperty;
private final Property<Boolean> applyGeneratedAnnotation;
private final SetProperty<String> suppressions;
private final Property<JavaVersion> javaVersion;
private final HibernateOrmSpec ormSpec;
private final DirectoryProperty resourcesOutputDir;
private final SourceSet mainSourceSet;
@Inject
@SuppressWarnings( "UnstableApiUsage" )
public JpaMetamodelGenerationTask(
HibernateOrmSpec ormSpec,
SourceSet mainSourceSet,
JavaCompile mainCompileTask,
Project project) {
this.ormSpec = ormSpec;
dependsOn( mainCompileTask );
public JpaMetamodelGenerationTask() {
setGroup( HIBERNATE );
setDescription( "Generates the JPA 'static metamodel'" );
this.mainSourceSet = mainSourceSet;
sourceSetProperty = getProject().getObjects().property( SourceSet.class );
final SourceSetOutput mainSourceSetOutput = mainSourceSet.getOutput();
generationOutputDirectory = getProject().getObjects().directoryProperty();
resourcesOutputDir = project.getObjects().directoryProperty();
resourcesOutputDir.set( project.getLayout().dir( project.provider( mainSourceSetOutput::getResourcesDir ) ) );
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() );
}
@InputFiles
@SkipWhenEmpty
public FileCollection getJavaClassDirs() {
return mainSourceSet.getOutput();
public void injectSourceSet(Provider<SourceSet> sourceSetAccess) {
sourceSetProperty.set( sourceSetAccess );
}
@InputFiles
@SkipWhenEmpty
public DirectoryProperty getResourcesOutputDir() {
// for access to XML mappings
return resourcesOutputDir;
public void injectJavaVersion(Object version) {
javaVersion.set( JavaVersion.toVersion( version ) );
}
@OutputDirectory
public DirectoryProperty getGenerationOutputDirectory() {
return ormSpec.getJpaMetamodelSpec().getGenerationOutputDirectory();
return generationOutputDirectory;
}
@InputFiles
@SkipWhenEmpty
public FileCollection getSources() {
return sourceSetProperty.get().getOutput();
}
@Input
public Property<Boolean> getApplyGeneratedAnnotation() {
return applyGeneratedAnnotation;
}
@Input
public SetProperty<String> getSuppressions() {
return suppressions;
}
@TaskAction
public void generateJpaMetamodel() {
final ClassLoader classLoader = determineUnitClassLoader( getProject(), mainSourceSet );
final ClassLoader classLoader = Helper.toClassLoader( sourceSetProperty.get().getOutput() );
final PersistenceUnitInfoImpl unitInfo = new PersistenceUnitInfoImpl(
determineUnitUrl(),
generateIntegrationSettings(),
classLoader
);
getJavaClassDirs().forEach(
classesDir -> {
final ConfigurableFileTree files = getProject().fileTree( classesDir );
files.forEach(
file -> {
if ( file.getName().endsWith( ".class" ) ) {
final String className = Helper.determineClassName( classesDir, file );
unitInfo.addManagedClassName( className );
}
else if ( isMappingFile( file ) ) {
unitInfo.addMappingFile( file.getName() );
}
}
);
}
);
resourcesOutputDir.getAsFileTree().forEach(
file -> {
if ( isMappingFile( file ) ) {
unitInfo.addMappingFile( file.getName() );
}
getSources().forEach( (dir) -> {
final ConfigurableFileTree files = getProject().fileTree( dir );
files.forEach( (file) -> {
if ( file.getName().endsWith( ".class" ) ) {
final String className = Helper.determineClassName( dir, file );
unitInfo.addManagedClassName( className );
}
);
else if ( isMappingFile( file ) ) {
unitInfo.addMappingFile( file.getName() );
}
} );
} );
JpaStaticMetamodelGenerator.processMetamodel( unitInfo, ormSpec.getJpaMetamodelSpec() );
JpaStaticMetamodelGenerator.processMetamodel( unitInfo, createGenerationOptions() );
}
private GenerationOptions createGenerationOptions() {
return new GenerationOptions() {
@Override
public Provider<Directory> getGenerationDirectory() {
return generationOutputDirectory;
}
@Override
public Provider<Boolean> getApplyGeneratedAnnotation() {
return applyGeneratedAnnotation;
}
@Override
public SetProperty<String> getSuppressions() {
return suppressions;
}
@Override
public Provider<JavaVersion> getTargetJavaVersionAccess() {
return javaVersion;
}
};
}
private URL determineUnitUrl() {
@ -148,25 +167,6 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
}
}
@SuppressWarnings( "UnstableApiUsage" )
private static ClassLoader determineUnitClassLoader(Project project, SourceSet mainSourceSet) {
final String compileJavaTaskName = mainSourceSet.getCompileJavaTaskName();
final JavaCompile javaCompileTask = (JavaCompile) project.getTasks().getByName( compileJavaTaskName );
final URL projectClassesDirUrl = toUrl( javaCompileTask.getDestinationDirectory().get().getAsFile() );
return new URLClassLoader( new URL[] { projectClassesDirUrl }, MetamodelClass.class.getClassLoader() );
}
private static URL toUrl(File file) {
final URI uri = file.toURI();
try {
return uri.toURL();
}
catch (MalformedURLException e) {
throw new GradleException( "Could not convert classpath entry into URL : " + file.getAbsolutePath(), e );
}
}
private Properties generateIntegrationSettings() {
final Properties settings = new Properties();
@ -186,151 +186,7 @@ public class JpaMetamodelGenerationTask extends DefaultTask {
return fileName.endsWith( ".hbm.xml" ) || fileName.endsWith( ".orm.xml" );
}
private static class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
private final URL unitRoot;
private final Properties properties;
private final ClassLoader classLoader;
private final List<String> managedClassNames = new ArrayList<>();
private final List<String> mappingFileNames = new ArrayList<>();
public PersistenceUnitInfoImpl(URL unitRoot, Properties properties, ClassLoader classLoader) {
this.unitRoot = unitRoot;
this.properties = properties;
this.classLoader = classLoader;
}
@Override
public String getPersistenceUnitName() {
return "jpa-static-metamodel-gen";
}
@Override
public URL getPersistenceUnitRootUrl() {
return unitRoot;
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public ClassLoader getClassLoader() {
return classLoader;
}
@Override
public List<String> getManagedClassNames() {
return managedClassNames;
}
public void addManagedClassName(String className) {
getManagedClassNames().add( className );
}
@Override
public List<String> getMappingFileNames() {
return mappingFileNames;
}
public void addMappingFile(String fileName) {
getMappingFileNames().add( fileName );
}
@Override
public String getPersistenceProviderClassName() {
return HibernatePersistenceProvider.class.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return null;
}
@Override
public DataSource getJtaDataSource() {
return null;
}
@Override
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<URL> getJarFileUrls() {
return null;
}
@Override
public boolean excludeUnlistedClasses() {
return true;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return null;
}
@Override
public ValidationMode getValidationMode() {
return null;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return null;
}
@Override
public void addTransformer(ClassTransformer transformer) {
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}
@SuppressWarnings( "UnstableApiUsage" )
public static void apply(HibernateOrmSpec pluginDsl, SourceSet mainSourceSet, Project project) {
final String mainCompileTaskName = mainSourceSet.getCompileJavaTaskName();
final JavaCompile mainCompileTask = (JavaCompile) project.getTasks().getByName( mainCompileTaskName );
final Task compileResourcesTask = project.getTasks().getByName( "processResources" );
final JpaMetamodelGenerationTask genTask = project.getTasks().create(
DSL_NAME,
JpaMetamodelGenerationTask.class,
pluginDsl,
mainSourceSet,
mainCompileTask,
project
);
genTask.setGroup( HIBERNATE );
genTask.setDescription( "Generates the JPA 'static metamodel'" );
genTask.onlyIf( (t) -> pluginDsl.getSupportJpaMetamodelProperty().getOrElse( true ) );
genTask.dependsOn( mainCompileTask );
genTask.dependsOn( compileResourcesTask );
final JavaCompile compileJpaMetamodelTask = project.getTasks().create( COMPILE_DSL_NAME, JavaCompile.class );
compileJpaMetamodelTask.setGroup( HIBERNATE );
compileJpaMetamodelTask.setDescription( "Compiles the JPA static metamodel generated by `" + DSL_NAME + "`" );
compileJpaMetamodelTask.setSourceCompatibility( mainCompileTask.getSourceCompatibility() );
compileJpaMetamodelTask.setTargetCompatibility( mainCompileTask.getTargetCompatibility() );
genTask.finalizedBy( compileJpaMetamodelTask );
mainCompileTask.finalizedBy( compileJpaMetamodelTask );
compileJpaMetamodelTask.dependsOn( genTask );
compileJpaMetamodelTask.source( project.files( pluginDsl.getJpaMetamodelSpec().getGenerationOutputDirectory() ) );
compileJpaMetamodelTask.getDestinationDirectory().set( pluginDsl.getJpaMetamodelSpec().getCompileOutputDirectory() );
compileJpaMetamodelTask.setClasspath(
project.getConfigurations().getByName( "runtimeClasspath" ).plus( mainSourceSet.getRuntimeClasspath() )
);
public static void apply(HibernateOrmSpec pluginDsl, Project project) {
}
}

View File

@ -0,0 +1,131 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.tooling.gradle.metamodel;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.ClassTransformer;
import jakarta.persistence.spi.PersistenceUnitInfo;
import jakarta.persistence.spi.PersistenceUnitTransactionType;
/**
* @author Steve Ebersole
*/
class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
private final URL unitRoot;
private final Properties properties;
private final ClassLoader classLoader;
private final List<String> managedClassNames = new ArrayList<>();
private final List<String> mappingFileNames = new ArrayList<>();
public PersistenceUnitInfoImpl(URL unitRoot, Properties properties, ClassLoader classLoader) {
this.unitRoot = unitRoot;
this.properties = properties;
this.classLoader = classLoader;
}
@Override
public String getPersistenceUnitName() {
return "jpa-static-metamodel-gen";
}
@Override
public URL getPersistenceUnitRootUrl() {
return unitRoot;
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public ClassLoader getClassLoader() {
return classLoader;
}
@Override
public List<String> getManagedClassNames() {
return managedClassNames;
}
public void addManagedClassName(String className) {
getManagedClassNames().add( className );
}
@Override
public List<String> getMappingFileNames() {
return mappingFileNames;
}
public void addMappingFile(String fileName) {
getMappingFileNames().add( fileName );
}
@Override
public String getPersistenceProviderClassName() {
return HibernatePersistenceProvider.class.getName();
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return null;
}
@Override
public DataSource getJtaDataSource() {
return null;
}
@Override
public DataSource getNonJtaDataSource() {
return null;
}
@Override
public List<URL> getJarFileUrls() {
return null;
}
@Override
public boolean excludeUnlistedClasses() {
return true;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return null;
}
@Override
public ValidationMode getValidationMode() {
return null;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return null;
}
@Override
public void addTransformer(ClassTransformer transformer) {
}
@Override
public ClassLoader getNewTempClassLoader() {
return null;
}
}

View File

@ -0,0 +1,22 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
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;
/**
* @author Steve Ebersole
*/
public interface GenerationOptions {
Provider<Directory> getGenerationDirectory();
Provider<Boolean> getApplyGeneratedAnnotation();
SetProperty<String> getSuppressions();
Provider<JavaVersion> getTargetJavaVersionAccess();
}

View File

@ -11,7 +11,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import jakarta.persistence.spi.PersistenceUnitInfo;
import org.gradle.api.file.Directory;
import org.gradle.api.file.RegularFile;
@ -23,22 +22,24 @@ import org.hibernate.mapping.Component;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationSpec;
import jakarta.persistence.spi.PersistenceUnitInfo;
public class JpaStaticMetamodelGenerator {
public static void processMetamodel(
PersistenceUnitInfo persistenceUnitInfo,
JpaMetamodelGenerationSpec spec) {
GenerationOptions options) {
EntityManagerFactoryBuilder target = Bootstrap.getEntityManagerFactoryBuilder( persistenceUnitInfo, Collections.emptyMap() );
try {
new JpaStaticMetamodelGenerator( spec, target.metadata() ).process();
new JpaStaticMetamodelGenerator( options, target.metadata() ).process();
}
finally {
target.cancel();
}
}
private final JpaMetamodelGenerationSpec spec;
private final GenerationOptions options;
private final MetadataImplementor metadata;
private final Directory generationOutputDirectory;
@ -46,10 +47,10 @@ public class JpaStaticMetamodelGenerator {
private final Set<String> processedDomainTypeNames = new HashSet<>();
private JpaStaticMetamodelGenerator(JpaMetamodelGenerationSpec spec, MetadataImplementor metadata) {
this.spec = spec;
private JpaStaticMetamodelGenerator(GenerationOptions options, MetadataImplementor metadata) {
this.options = options;
this.metadata = metadata;
this.generationOutputDirectory = spec.getGenerationOutputDirectory().get();
this.generationOutputDirectory = options.getGenerationDirectory().get();
this.objectFactory = new ObjectFactory( metadata );
}
@ -94,10 +95,9 @@ public class JpaStaticMetamodelGenerator {
final RegularFile metamodelClassJavaFile = generationOutputDirectory.file( metamodelClassJavaFileName );
final File metamodelClassJavaFileAsFile = metamodelClassJavaFile.getAsFile();
metamodelClass.writeToFile( metamodelClassJavaFileAsFile, spec );
metamodelClass.writeToFile( metamodelClassJavaFileAsFile, options );
}
@SuppressWarnings( "unchecked" )
private void handleEmbeddable(Component embeddedValueMapping) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( embeddedValueMapping );
handleManagedClass( metamodelClass, embeddedValueMapping.getPropertyIterator() );

View File

@ -24,8 +24,6 @@ import java.util.TreeSet;
import org.gradle.api.GradleException;
import org.gradle.api.JavaVersion;
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationSpec;
import static java.lang.Character.LINE_SEPARATOR;
/**
@ -59,14 +57,14 @@ public class MetamodelClass {
attributes.add( attribute );
}
public void writeToFile(File outputFile, JpaMetamodelGenerationSpec spec) {
public void writeToFile(File outputFile, GenerationOptions options) {
prepareOutputFile( outputFile );
final Path path = outputFile.toPath();
try ( final BufferedWriter writer = Files.newBufferedWriter( path, StandardCharsets.UTF_8, StandardOpenOption.WRITE ) ) {
renderClassPreamble( writer, spec );
renderClassPreamble( writer, options );
writer.write( LINE_SEPARATOR );
writer.write( "public abstract class " + metamodelClassName );
@ -96,7 +94,7 @@ public class MetamodelClass {
}
}
private void renderClassPreamble(BufferedWriter writer, JpaMetamodelGenerationSpec spec) throws IOException {
private void renderClassPreamble(BufferedWriter writer, GenerationOptions options) throws IOException {
final String nowFormatted = DateFormat.getDateInstance().format( new Date() );
writer.write( "// Generated by Hibernate ORM Gradle tooling - " + nowFormatted );
@ -113,8 +111,8 @@ public class MetamodelClass {
writer.write( LINE_SEPARATOR );
// first, the generated annotation
if ( spec.getApplyGeneratedAnnotation().getOrElse( true ) ) {
final JavaVersion javaVersion = spec.getTargetJavaVersionAccess().getOrElse( JavaVersion.current() );
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";
@ -130,7 +128,7 @@ public class MetamodelClass {
writer.write( LINE_SEPARATOR );
}
final Set<String> suppressions = spec.getSuppressions().getOrElse( Collections.emptySet() );
final Set<String> suppressions = options.getSuppressions().getOrElse( Collections.emptySet() );
if ( ! suppressions.isEmpty() ) {
writer.write( "@SuppressWarnings( { " );
for ( String suppression : suppressions ) {

View File

@ -14,13 +14,9 @@ import org.gradle.testkit.runner.BuildTask;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.hibernate.engine.spi.Managed;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.assertj.core.api.Condition;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@ -29,15 +25,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
*
* @author Steve Ebersole
*/
class HibernateOrmPluginTest {
private static final Condition<TaskOutcome> SUCCESS = new Condition<>(
(taskOutcome) -> taskOutcome == TaskOutcome.SUCCESS,
"task succeeded"
);
private static final Condition<TaskOutcome> UP_TO_DATE = new Condition<>(
(taskOutcome) -> taskOutcome == TaskOutcome.UP_TO_DATE,
"task up-to-date"
);
class JavaProjectTests {
@Test
public void testEnhancement(@TempDir Path projectDir) throws Exception {
@ -59,13 +47,8 @@ class HibernateOrmPluginTest {
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEmbeddable" );
verifyEnhanced( classLoader, "TheEntity" );
}
private void verifyEnhanced(ClassLoader classLoader, String className) throws Exception {
final Class<?> loadedClass = classLoader.loadClass( className );
assertThat( Managed.class ).isAssignableFrom( loadedClass );
TestHelper.verifyEnhanced( classLoader, "TheEmbeddable" );
TestHelper.verifyEnhanced( classLoader, "TheEntity" );
}
@Test
@ -89,7 +72,7 @@ class HibernateOrmPluginTest {
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
TestHelper.verifyEnhanced( classLoader, "TheEntity" );
}
{
@ -108,7 +91,7 @@ class HibernateOrmPluginTest {
// and again
final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
TestHelper.verifyEnhanced( classLoader, "TheEntity" );
}
}
@ -127,10 +110,10 @@ class HibernateOrmPluginTest {
final BuildTask task = result.task( ":generateJpaMetamodel" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
@Test
// @Disabled( "up-to-date checking not working" )
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
Copier.copyProject( "simple/build.gradle", projectDir );
@ -147,6 +130,7 @@ class HibernateOrmPluginTest {
final BuildTask task = result.task( ":generateJpaMetamodel" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
{
@ -162,75 +146,7 @@ class HibernateOrmPluginTest {
final BuildTask task2 = result2.task( ":generateJpaMetamodel" );
assertThat( task2 ).isNotNull();
assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
}
@Test
public void testEnhanceKotlinModel(@TempDir Path projectDir) throws Exception {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
@Test
public void testEnhanceKotlinModelUpToDate(@TempDir Path projectDir) throws Exception {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
{
System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
{
System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
}
}

View File

@ -0,0 +1,150 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.tooling.gradle;
import java.io.File;
import java.nio.file.Path;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.BuildTask;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hibernate.orm.tooling.gradle.TestHelper.verifyEnhanced;
/**
* @author Steve Ebersole
*/
public class KotlinProjectTests {
@Test
public void testEnhanceModel(@TempDir Path projectDir) throws Exception {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
@Test
public void testEnhanceModelUpToDate(@TempDir Path projectDir) throws Exception {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
{
System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
{
System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "compileKotlin", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":compileKotlin" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE );
// make sure the class is enhanced
final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" );
final ClassLoader classLoader = Helper.toClassLoader( classesDir );
verifyEnhanced( classLoader, "TheEntity" );
}
}
@Test
public void testJpaMetamodelGen(@TempDir Path projectDir) {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":generateJpaMetamodel" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
@Test
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
Copier.copyProject( "simple-kotlin/build.gradle", projectDir );
{
System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result = gradleRunner.build();
final BuildTask task = result.task( ":generateJpaMetamodel" );
assertThat( task ).isNotNull();
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
{
System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
final GradleRunner gradleRunner2 = GradleRunner.create()
.withProjectDir( projectDir.toFile() )
.withPluginClasspath()
.withDebug( true )
.withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
.forwardOutput();
final BuildResult result2 = gradleRunner2.build();
final BuildTask task2 = result2.task( ":generateJpaMetamodel" );
assertThat( task2 ).isNotNull();
assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE );
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
}
}
}

View File

@ -0,0 +1,34 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.orm.tooling.gradle;
import org.gradle.testkit.runner.TaskOutcome;
import org.hibernate.engine.spi.Managed;
import org.assertj.core.api.Condition;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
/**
* @author Steve Ebersole
*/
public class TestHelper {
private static final Condition<TaskOutcome> SUCCESS = new Condition<>(
(taskOutcome) -> taskOutcome == TaskOutcome.SUCCESS,
"task succeeded"
);
private static final Condition<TaskOutcome> UP_TO_DATE = new Condition<>(
(taskOutcome) -> taskOutcome == TaskOutcome.UP_TO_DATE,
"task up-to-date"
);
public static void verifyEnhanced(ClassLoader classLoader, String className) throws Exception {
final Class<?> loadedClass = classLoader.loadClass( className );
assertThat( Managed.class ).isAssignableFrom( loadedClass );
}
}

View File

@ -20,10 +20,13 @@ repositories {
}
dependencies {
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final'
}
hibernate {
// to get using the same version to work, we'd have to install hibernate-core into maven local prior to running these.
// suck we won't be able to adequately test this part, but
useSameVersion = false
enhancement {
lazyInitialization( true )
dirtyTracking = true

View File

@ -1,7 +1,9 @@
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.annotations.BatchSize
@Entity
@BatchSize(size = 20)
class TheEntity (
@Id
var id: Long? = null,

View File

@ -20,10 +20,13 @@ repositories {
}
dependencies {
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final'
}
hibernate {
// to get using the same version to work, we'd have to install hibernate-core into maven local prior to running these.
// suck we won't be able to adequately test this part, but
useSameVersion = false
enhancement {
lazyInitialization( true )
dirtyTracking = true

View File

@ -12,9 +12,12 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import org.hibernate.annotations.BatchSize;
import java.util.Set;
@Entity
@BatchSize( size = 20 )
public class TheEntity {
@Id
private Integer id;