HHH-16677 - Drop JPA static metamodel generation from Gradle plugin

This commit is contained in:
Steve Ebersole 2023-05-23 11:00:20 -05:00
parent 2bebcf5e95
commit 2e98c1678d
25 changed files with 0 additions and 1426 deletions

View File

@ -13,21 +13,11 @@ 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;
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.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
@ -42,7 +32,6 @@ 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 );
@ -94,64 +83,6 @@ public class HibernateOrmPlugin implements Plugin<Project> {
} );
}
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().convention( 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();
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() );
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() );
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 );
} );
}
private void prepareHbmTransformation(HibernateOrmSpec ormDsl, Project project) {
}

View File

@ -20,7 +20,6 @@ import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.SourceSet;
import org.hibernate.orm.tooling.gradle.enhance.EnhancementSpec;
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationSpec;
/**
* Main DSL extension for Hibernate ORM. Available as `project.hibernate`
@ -33,14 +32,12 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
private final Project project;
private EnhancementSpec enhancementDsl;
private JpaMetamodelGenerationSpec jpaMetamodelDsl;
private final Property<Boolean> useSameVersion;
private final Property<SourceSet> sourceSet;
private final SetProperty<String> languages;
private final Provider<EnhancementSpec> enhancementDslAccess;
private final Provider<JpaMetamodelGenerationSpec> jpaMetamodelDslAccess;
@Inject
@ -57,7 +54,6 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
languages.convention( Arrays.asList( "java", "kotlin" ) );
enhancementDslAccess = project.provider( () -> enhancementDsl );
jpaMetamodelDslAccess = project.provider( () -> jpaMetamodelDsl );
}
private static SourceSet mainSourceSet(Project project) {
@ -121,33 +117,11 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
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;
}
/**
* @see #getJpaMetamodel()
*/
public void jpaMetamodel(Action<JpaMetamodelGenerationSpec>action) {
action.execute( getJpaMetamodel() );
}
public boolean isEnhancementEnabled() {
return enhancementDsl != null;
}
public boolean isMetamodelGenerationEnabled() {
return jpaMetamodelDsl != null;
}
/**
* @see #getUseSameVersion()
@ -238,15 +212,4 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
public Provider<EnhancementSpec> getEnhancementDslAccess() {
return enhancementDslAccess;
}
/**
* Provider access to {@link #getJpaMetamodel()}
*
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
*/
@Deprecated
public Provider<JpaMetamodelGenerationSpec> getJpaMetamodelDslAccess() {
return jpaMetamodelDslAccess;
}
}

View File

@ -1,111 +0,0 @@
/*
* 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.util.Arrays;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.SetProperty;
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
/**
* @author Steve Ebersole
*/
public class JpaMetamodelGenerationSpec {
public static final String JPA_METAMODEL = "jpaMetamodel";
public static final String DSL_NAME = JPA_METAMODEL;
private final Project project;
private final DirectoryProperty generationOutputDirectory;
private final DirectoryProperty compileOutputDirectory;
private final Property<Boolean> applyGeneratedAnnotation;
private final SetProperty<String> suppressions;
@Inject
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
this.project = project;
generationOutputDirectory = project.getObjects().directoryProperty();
generationOutputDirectory.convention(
project.getLayout().getBuildDirectory().dir( "generated/sources/" + JPA_METAMODEL )
);
compileOutputDirectory = project.getObjects().directoryProperty();
compileOutputDirectory.convention(
project.getLayout().getBuildDirectory().dir( "classes/java/" + JPA_METAMODEL )
);
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
applyGeneratedAnnotation.convention( true );
suppressions = project.getObjects().setProperty( String.class );
suppressions.convention( Arrays.asList( "raw", "deprecation" ) );
}
public Property<Boolean> getApplyGeneratedAnnotation() {
return applyGeneratedAnnotation;
}
public SetProperty<String> getSuppressions() {
return suppressions;
}
public DirectoryProperty getGenerationOutputDirectory() {
return generationOutputDirectory;
}
public DirectoryProperty getCompileOutputDirectory() {
return compileOutputDirectory;
}
/**
* @see #getApplyGeneratedAnnotation()
*
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
*/
@Deprecated(forRemoval = true)
public void applyGeneratedAnnotation(boolean apply) {
applyGeneratedAnnotation.set( apply );
}
/**
* @see #getSuppressions()
*
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
*/
@Deprecated(forRemoval = true)
public void suppress(String warning) {
suppressions.add( warning );
}
/**
* @see #getGenerationOutputDirectory()
*
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
*/
@Deprecated(forRemoval = true)
public void generationOutputDirectory(Object ref) {
generationOutputDirectory.set( project.file( ref ) );
}
/**
* @see #getCompileOutputDirectory()
*
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
*/
@Deprecated(forRemoval = true)
public void compileOutputDirectory(Object ref) {
compileOutputDirectory.set( project.file( ref ) );
}
}

View File

@ -1,177 +0,0 @@
/*
* 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.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import javax.inject.Inject;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
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.TaskAction;
import org.hibernate.cfg.AvailableSettings;
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 static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
/**
* Generates the "JPA static metamodel" from the domain model defined by the project
* via classes and possibly XML mappings
*
* @apiNote While there is also an annotation-processor that performs the same
* general function, that approach is limited in that it can only process compiled
* classes based on annotations. This task accounts for both classes and XML mappings
*/
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<Boolean> applyGeneratedAnnotation;
private final SetProperty<String> suppressions;
@Inject
public JpaMetamodelGenerationTask() {
setGroup( HIBERNATE );
setDescription( "Generates the JPA 'static metamodel'" );
sourceSetProperty = getProject().getObjects().property( SourceSet.class );
generationOutputDirectory = getProject().getObjects().directoryProperty();
applyGeneratedAnnotation = getProject().getObjects().property( Boolean.class );
suppressions = getProject().getObjects().setProperty( String.class );
}
public void injectSourceSet(Provider<SourceSet> sourceSetAccess) {
sourceSetProperty.set( sourceSetAccess );
}
@OutputDirectory
public DirectoryProperty 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 = Helper.toClassLoader( sourceSetProperty.get().getOutput() );
final PersistenceUnitInfoImpl unitInfo = new PersistenceUnitInfoImpl(
determineUnitUrl(),
generateIntegrationSettings(),
classLoader
);
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, 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;
}
};
}
private URL determineUnitUrl() {
try {
// NOTE : we just need *a* URL - we used the project dir
return getProject().getProjectDir().toURI().toURL();
}
catch (MalformedURLException e) {
throw new IllegalStateException( "Could not interpret project directory as URL" );
}
}
private Properties generateIntegrationSettings() {
final Properties settings = new Properties();
settings.put( "hibernate.temp.use_jdbc_metadata_defaults", "false" );
settings.put( AvailableSettings.DIALECT, "H2" );
settings.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, false );
settings.put( AvailableSettings.USE_QUERY_CACHE, false );
return settings;
}
private boolean isMappingFile(File file) {
final String fileName = file.getName();
// convention
// - we could allow filters for flexibility?
return fileName.endsWith( ".hbm.xml" ) || fileName.endsWith( ".orm.xml" );
}
public static void apply(HibernateOrmSpec pluginDsl, Project project) {
// todo : implement it
}
}

View File

@ -1,131 +0,0 @@
/*
* 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

@ -1,34 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
import java.util.Collection;
public class AttributeBag extends AttributeSupport {
private final Class<?> elementJavaType;
public AttributeBag(
MetamodelClass metamodelClass,
String attributeName,
Class<?> elementJavaType) {
super( metamodelClass, attributeName, Collection.class );
this.elementJavaType = elementJavaType;
}
@Override
public void renderAttributeType(BufferedWriter writer) throws IOException {
writer.write(
format(
"CollectionAttribute<%s,%s>",
getOwnerDomainClassName(),
elementJavaType.getName()
)
);
}
}

View File

@ -1,34 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
import java.util.Set;
public class AttributeList extends AttributeSupport {
private final Class<?> elementJavaType;
public AttributeList(
MetamodelClass metamodelClass,
String attributeName,
Class<?> elementJavaType) {
super( metamodelClass, attributeName, Set.class );
this.elementJavaType = elementJavaType;
}
@Override
public void renderAttributeType(BufferedWriter writer) throws IOException {
writer.write(
format(
"ListAttribute<%s,%s>",
getOwnerDomainClassName(),
elementJavaType.getName()
)
);
}
}

View File

@ -1,38 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
import java.util.Set;
public class AttributeMap extends AttributeSupport {
private final Class<?> keyJavaType;
private final Class<?> elementJavaType;
public AttributeMap(
MetamodelClass metamodelClass,
String attributeName,
Class<?> keyJavaType,
Class<?> elementJavaType) {
super( metamodelClass, attributeName, Set.class );
this.keyJavaType = keyJavaType;
this.elementJavaType = elementJavaType;
}
@Override
public void renderAttributeType(BufferedWriter writer) throws IOException {
writer.write(
format(
"MapAttribute<%s,%s,%s>",
getOwnerDomainClassName(),
keyJavaType.getName(),
elementJavaType.getName()
)
);
}
}

View File

@ -1,34 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
import java.util.Set;
public class AttributeSet extends AttributeSupport {
private final Class<?> elementJavaType;
public AttributeSet(
MetamodelClass metamodelClass,
String attributeName,
Class<?> elementJavaType) {
super( metamodelClass, attributeName, Set.class );
this.elementJavaType = elementJavaType;
}
@Override
public void renderAttributeType(BufferedWriter writer) throws IOException {
writer.write(
format(
"SetAttribute<%s,%s>",
getOwnerDomainClassName(),
elementJavaType.getName()
)
);
}
}

View File

@ -1,29 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
public class AttributeSingular extends AttributeSupport {
public AttributeSingular(MetamodelClass metamodelClass, String name, Class javaType) {
super( metamodelClass, name, javaType );
}
@Override
public void renderAttributeType(BufferedWriter writer) throws IOException {
// JPA stuff already imported
writer.write(
format(
"SingularAttribute<%s,%s>",
getOwnerDomainClassName(),
getAttributeJavaType().getName()
)
);
}
}

View File

@ -1,75 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.IOException;
import java.util.Locale;
import static java.lang.Character.LINE_SEPARATOR;
public abstract class AttributeSupport implements MetamodelAttribute {
private final MetamodelClass metamodelClass;
private final String name;
private final Class<?> javaType;
public AttributeSupport(
MetamodelClass metamodelClass,
String name,
Class<?> javaType) {
this.metamodelClass = metamodelClass;
this.name = name;
this.javaType = javaType;
}
@Override
public String getName() {
return name;
}
@Override
public Class<?> getAttributeJavaType() {
return javaType;
}
public String getOwnerDomainClassName() {
return metamodelClass.getMetamodelClassName();
}
@Override
public void renderJpaMembers(BufferedWriter writer) {
try {
writer.write( " public static volatile " );
renderAttributeType( writer );
writer.write( " " + name );
writer.write( ';' );
writer.write( LINE_SEPARATOR );
}
catch (IOException e) {
throw new IllegalStateException( "Problem writing attribute `" + metamodelClass.getMetamodelClassName() + "#" + name + "` to output stream", e );
}
}
public abstract void renderAttributeType(BufferedWriter writer) throws IOException;
protected String format(String pattern, Object... args) {
return String.format( Locale.ROOT, pattern, args );
}
@Override
public void renderNameConstant(BufferedWriter writer) {
try {
writer.write( " public static final String " );
writer.write( getName().toUpperCase( Locale.ROOT ) );
writer.write( " = \"" + getName() + "\";" );
writer.write( LINE_SEPARATOR );
}
catch (IOException e) {
throw new IllegalStateException( "Problem writing attribute `" + metamodelClass.getMetamodelClassName() + "#" + name + "` to output stream", e );
}
}
}

View File

@ -1,20 +0,0 @@
/*
* 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.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();
}

View File

@ -1,101 +0,0 @@
/*
* 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 java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.gradle.api.file.Directory;
import org.gradle.api.file.RegularFile;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import jakarta.persistence.spi.PersistenceUnitInfo;
import static java.util.Collections.emptyMap;
import static org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder;
public class JpaStaticMetamodelGenerator {
public static void processMetamodel(PersistenceUnitInfo persistenceUnitInfo, GenerationOptions options) {
final EntityManagerFactoryBuilder target = getEntityManagerFactoryBuilder( persistenceUnitInfo, emptyMap() );
try {
new JpaStaticMetamodelGenerator( options, target.metadata() ).process();
}
finally {
target.cancel();
}
}
private final GenerationOptions options;
private final MetadataImplementor metadata;
private final Directory generationOutputDirectory;
private final ObjectFactory objectFactory;
private final Set<String> processedDomainTypeNames = new HashSet<>();
private JpaStaticMetamodelGenerator(GenerationOptions options, MetadataImplementor metadata) {
this.options = options;
this.metadata = metadata;
this.generationOutputDirectory = options.getGenerationDirectory().get();
this.objectFactory = new ObjectFactory( metadata );
}
private void process() {
final Set<MappedSuperclass> mappedSuperclasses = metadata.getMappedSuperclassMappingsCopy();
if ( mappedSuperclasses != null ) {
mappedSuperclasses.forEach( this::handleMappedClass );
}
final Collection<PersistentClass> entityBindings = metadata.getEntityBindings();
if ( entityBindings != null ) {
entityBindings.forEach( this::handlePersistentClass );
}
}
private void handleMappedClass(MappedSuperclass mappingDescriptor) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( mappingDescriptor );
handleManagedClass( metamodelClass, mappingDescriptor.getDeclaredProperties() );
}
private void handlePersistentClass(PersistentClass persistentClass) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( persistentClass );
handleManagedClass( metamodelClass, persistentClass.getDeclaredProperties() );
}
private void handleManagedClass(MetamodelClass metamodelClass, List<Property> properties) {
if ( processedDomainTypeNames.add( metamodelClass.getDomainClassName() ) ) {
// not yet processed
for ( Property property : properties ) {
metamodelClass.addAttribute(
objectFactory.attribute( property, property.getValue(), metamodelClass, this::handleEmbeddable )
);
}
final String replaced = metamodelClass.getMetamodelClassName().replace( '.', '/' );
final String metamodelClassJavaFileName = replaced + ".java";
final RegularFile metamodelClassJavaFile = generationOutputDirectory.file( metamodelClassJavaFileName );
final File metamodelClassJavaFileAsFile = metamodelClassJavaFile.getAsFile();
metamodelClass.writeToFile( metamodelClassJavaFileAsFile, options );
}
}
private void handleEmbeddable(Component embeddedValueMapping) {
final MetamodelClass metamodelClass = objectFactory.metamodelClass( embeddedValueMapping );
handleManagedClass( metamodelClass, embeddedValueMapping.getProperties() );
}
}

View File

@ -1,19 +0,0 @@
/*
* 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 java.io.BufferedWriter;
public interface MetamodelAttribute {
String getName();
Class<?> getAttributeJavaType();
void renderJpaMembers(BufferedWriter writer);
void renderNameConstant(BufferedWriter writer);
}

View File

@ -1,148 +0,0 @@
/*
* 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 java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.text.DateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import org.gradle.api.GradleException;
import static java.lang.Character.LINE_SEPARATOR;
/**
* Descriptor for a class in the JPA static metamodel being generated
*/
public class MetamodelClass {
private final String domainClassName;
private final String metamodelClassName;
private final String metamodelSuperClassName;
private final TreeSet<MetamodelAttribute> attributes = new TreeSet<>( Comparator.comparing( MetamodelAttribute::getName ) );
public MetamodelClass(String domainClassName, String superTypeName) {
this.domainClassName = domainClassName;
this.metamodelClassName = domainClassName + "_";
this.metamodelSuperClassName = superTypeName == null ? null : superTypeName + "_";
}
public String getMetamodelClassName() {
return metamodelClassName;
}
public String getDomainClassName() {
return domainClassName;
}
public void addAttribute(MetamodelAttribute attribute) {
assert attribute != null;
attributes.add( attribute );
}
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, options );
writer.write( LINE_SEPARATOR );
writer.write( "public abstract class " + metamodelClassName );
if ( metamodelSuperClassName != null ) {
writer.write( " extends " + metamodelSuperClassName );
}
writer.write( " {" );
writer.write( LINE_SEPARATOR );
writer.write( LINE_SEPARATOR );
writer.write( " // Attribute name constants" );
writer.write( LINE_SEPARATOR );
attributes.forEach( attribute -> attribute.renderNameConstant( writer ) );
writer.write( LINE_SEPARATOR );
writer.write( LINE_SEPARATOR );
writer.write( " // JPA static metamodel fields" );
writer.write( LINE_SEPARATOR );
attributes.forEach( attribute -> attribute.renderJpaMembers( writer ) );
writer.write( LINE_SEPARATOR );
writer.write( "}" );
writer.write( LINE_SEPARATOR );
}
catch (IOException e) {
throw new IllegalStateException( "Unable to open file : " + outputFile.getAbsolutePath(), e );
}
}
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 );
writer.write( LINE_SEPARATOR );
writer.write( LINE_SEPARATOR );
writer.write( "import jakarta.persistence.*;" );
writer.write( LINE_SEPARATOR );
writer.write( "import jakarta.persistence.metamodel.*;" );
writer.write( LINE_SEPARATOR );
writer.write( LINE_SEPARATOR );
writer.write( "/** JPA static metamodel descriptor for the `" + domainClassName + "` domain class */" );
writer.write( LINE_SEPARATOR );
// first, the generated annotation
if ( options.getApplyGeneratedAnnotation().getOrElse( true ) ) {
final String generatedAnnotationFragment = String.format(
Locale.ROOT,
"@jakarta.annotation.Generated( value=\"%s\", date=\"%s\", comments=\"%s\" )",
JpaStaticMetamodelGenerator.class.getName(),
nowFormatted,
"Generated by Hibernate ORM Gradle tooling"
);
writer.write( generatedAnnotationFragment );
writer.write( LINE_SEPARATOR );
}
final Set<String> suppressions = options.getSuppressions().getOrElse( Collections.emptySet() );
if ( ! suppressions.isEmpty() ) {
writer.write( "@SuppressWarnings( { " );
for ( String suppression : suppressions ) {
writer.write( "\"" + suppression + "\", " );
}
writer.write( " } )" );
writer.write( LINE_SEPARATOR );
}
writer.write( "@StaticMetamodel( " + domainClassName + ".class )" );
}
@SuppressWarnings( "ResultOfMethodCallIgnored" )
public void prepareOutputFile(File outputFile) {
try {
outputFile.getParentFile().mkdirs();
outputFile.createNewFile();
}
catch (IOException e) {
throw new GradleException( "Unable to prepare output file `" + outputFile.getAbsolutePath() + "`", e );
}
}
}

View File

@ -1,237 +0,0 @@
/*
* 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 java.util.Locale;
import java.util.function.Consumer;
import org.gradle.api.GradleException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Bag;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.List;
import org.hibernate.mapping.Map;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Set;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
/**
* @author Steve Ebersole
*/
public class ObjectFactory {
private final MetadataImplementor metadata;
public ObjectFactory(MetadataImplementor metadata) {
this.metadata = metadata;
}
public MetamodelClass metamodelClass(PersistentClass entityDescriptor) {
return new MetamodelClass( entityDescriptor.getMappedClass().getName(), determineSuperTypeName( entityDescriptor ) );
}
private String determineSuperTypeName(PersistentClass entityDescriptor) {
if ( entityDescriptor.getSuperMappedSuperclass() != null ) {
return entityDescriptor.getSuperMappedSuperclass().getMappedClass().getName();
}
if ( entityDescriptor.getSuperclass() != null ) {
return entityDescriptor.getSuperclass().getMappedClass().getName();
}
return null;
}
public MetamodelClass metamodelClass(MappedSuperclass mappedSuperclassDescriptor) {
return new MetamodelClass( mappedSuperclassDescriptor.getMappedClass().getName(), determineSuperTypeName( mappedSuperclassDescriptor ) );
}
private String determineSuperTypeName(MappedSuperclass mappedSuperclassDescriptor) {
if ( mappedSuperclassDescriptor.getSuperMappedSuperclass() != null ) {
return mappedSuperclassDescriptor.getSuperMappedSuperclass().getMappedClass().getName();
}
if ( mappedSuperclassDescriptor.getSuperPersistentClass() != null ) {
return mappedSuperclassDescriptor.getSuperPersistentClass().getMappedClass().getName();
}
return null;
}
public MetamodelClass metamodelClass(Component embeddedMapping) {
return new MetamodelClass( embeddedMapping.getComponentClassName(), null );
}
public MetamodelAttribute attribute(
Property property,
Value propertyValueMapping,
MetamodelClass metamodelClass,
Consumer<Component> componentConsumer) {
if ( propertyValueMapping instanceof DependantValue ) {
final DependantValue dependantValue = (DependantValue) propertyValueMapping;
final KeyValue wrappedValue = dependantValue.getWrappedValue();
return attribute( property, wrappedValue, metamodelClass, componentConsumer );
}
if ( propertyValueMapping instanceof Collection ) {
return pluralAttribute( property, (Collection) propertyValueMapping, metamodelClass, componentConsumer );
}
final Class<?> propertyJavaType = determineSingularJavaType( property, propertyValueMapping, metamodelClass, componentConsumer );
return new AttributeSingular( metamodelClass, property.getName(), propertyJavaType );
}
private Class<?> determineSingularJavaType(
Property property,
Value propertyValueMapping,
MetamodelClass metamodelClass,
Consumer<Component> componentConsumer) {
if ( propertyValueMapping instanceof BasicValue ) {
final BasicValue basicValue = (BasicValue) propertyValueMapping;
return basicValue.resolve().getDomainJavaType().getJavaTypeClass();
}
if ( propertyValueMapping instanceof Component ) {
final Component component = (Component) propertyValueMapping;
componentConsumer.accept( component );
return component.getComponentClass();
}
if ( propertyValueMapping instanceof Any ) {
return Object.class;
}
if ( propertyValueMapping instanceof ToOne ) {
final ToOne toOne = (ToOne) propertyValueMapping;
final String referencedEntityName = toOne.getReferencedEntityName();
final PersistentClass entityBinding = metadata.getEntityBinding( referencedEntityName );
final Class<?> mappedClass = entityBinding.getMappedClass();
if ( mappedClass == null ) {
throw new GradleException(
String.format(
Locale.ROOT,
"Could not determine ToOne java type : %s#%s",
metamodelClass.getDomainClassName(),
property.getName()
)
);
}
return mappedClass;
}
propertyValueMapping.setTypeUsingReflection( metamodelClass.getDomainClassName(), property.getName() );
return propertyValueMapping.getType().getReturnedClass();
}
private MetamodelAttribute pluralAttribute(
Property property,
Collection collectionMapping,
MetamodelClass metamodelClass,
Consumer<Component> componentConsumer) {
if ( collectionMapping instanceof Set ) {
return new AttributeSet(
metamodelClass,
property.getName(),
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
);
}
if ( collectionMapping instanceof Bag ) {
return new AttributeBag(
metamodelClass,
property.getName(),
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
);
}
if ( collectionMapping instanceof List ) {
return new AttributeList(
metamodelClass,
property.getName(),
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
);
}
if ( collectionMapping instanceof Map ) {
return new AttributeMap(
metamodelClass,
property.getName(),
determineCollectionPartJavaType( property, ( (Map) collectionMapping ).getIndex(), metamodelClass, componentConsumer ),
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
);
}
throw new UnsupportedOperationException( "Unsupported plural value type : " + collectionMapping.getClass().getName() );
}
private Class<?> determineCollectionPartJavaType(
Property property,
Value partJavaType,
MetamodelClass metamodelClass,
Consumer<Component> componentConsumer) {
if ( partJavaType instanceof DependantValue ) {
final DependantValue dependantValue = (DependantValue) partJavaType;
final KeyValue wrappedValue = dependantValue.getWrappedValue();
return determineCollectionPartJavaType( property, wrappedValue, metamodelClass, componentConsumer );
}
if ( partJavaType instanceof BasicValue ) {
final BasicValue basicValue = (BasicValue) partJavaType;
return basicValue.resolve().getDomainJavaType().getJavaTypeClass();
}
if ( partJavaType instanceof Component ) {
final Component component = (Component) partJavaType;
componentConsumer.accept( component );
return component.getComponentClass();
}
if ( partJavaType instanceof Any ) {
return Object.class;
}
if ( partJavaType instanceof OneToMany ) {
final OneToMany oneToMany = (OneToMany) partJavaType;
final PersistentClass associatedClass = oneToMany.getAssociatedClass();
return associatedClass.getMappedClass();
}
if ( partJavaType instanceof ToOne ) {
final ToOne toOne = (ToOne) partJavaType;
final String referencedEntityName = toOne.getReferencedEntityName();
if ( referencedEntityName != null ) {
final PersistentClass entityBinding = metadata.getEntityBinding( referencedEntityName );
if ( entityBinding != null ) {
final Class<?> mappedClass = entityBinding.getMappedClass();
if ( mappedClass != null ) {
return mappedClass;
}
}
}
throw new GradleException(
String.format(
Locale.ROOT,
"Could not determine ToOne java type : %s#%s",
metamodelClass.getDomainClassName(),
property.getName()
)
);
}
return partJavaType.getType().getReturnedClass();
}
}

View File

@ -50,15 +50,4 @@ class JavaProjectTests extends TestsBase {
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
super.testEnhancementUpToDate( projectDir );
}
@Test
@Override
public void testJpaMetamodelGen(@TempDir Path projectDir) {
super.testJpaMetamodelGen( projectDir );
}
@Test
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
super.testJpaMetamodelGenUpToDate( projectDir );
}
}

View File

@ -47,16 +47,4 @@ public class KotlinProjectTests extends TestsBase {
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
super.testEnhancementUpToDate( projectDir );
}
@Test
@Override
public void testJpaMetamodelGen(@TempDir Path projectDir) {
super.testJpaMetamodelGen( projectDir );
}
@Test
@Override
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
super.testJpaMetamodelGenUpToDate( projectDir );
}
}

View File

@ -40,14 +40,4 @@ public class MultiPartNameTests extends TestsBase {
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
super.testEnhancementUpToDate( projectDir );
}
@Test
public void testJpaMetamodelGen(@TempDir Path projectDir) {
super.testJpaMetamodelGen( projectDir );
}
@Test
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
super.testJpaMetamodelGenUpToDate( projectDir );
}
}

View File

@ -9,7 +9,6 @@ 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;
@ -98,63 +97,4 @@ public abstract class TestsBase {
}
}
@Test
public void testJpaMetamodelGen(@TempDir Path projectDir) {
final String buildFilePath = getProjectName() + "/build.gradle";
Copier.copyProject( buildFilePath, projectDir );
System.out.println( "Starting 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();
}
@Test
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
final String buildFilePath = getProjectName() + "/build.gradle";
Copier.copyProject( buildFilePath, projectDir );
{
System.out.println( "Starting 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( "Starting 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

@ -43,6 +43,4 @@ hibernate {
enableDirtyTracking.set(true)
dirtyTracking = true
}
jpaMetamodel {
}
}

View File

@ -34,6 +34,4 @@ hibernate {
enableDirtyTracking.set(true)
dirtyTracking = true
}
jpaMetamodel {
}
}

View File

@ -34,6 +34,4 @@ hibernate {
enableDirtyTracking.set(true)
dirtyTracking = true
}
jpaMetamodel {
}
}

View File

@ -1,33 +0,0 @@
/*
* 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
*/
plugins {
id 'java'
id 'org.hibernate.orm'
}
repositories {
mavenCentral()
maven {
name 'jboss-snapshots-repository'
url 'https://repository.jboss.org/nexus/content/repositories/snapshots'
}
}
dependencies {
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
}
hibernate {
enhancement {
lazyInitialization( true )
dirtyTracking = true
}
jpaMetamodel {
}
}