* HHH-14634 : Gradle Enterprise

* fixed problem in release.gradle that caused "configuration phase" to take much longer than it should
   * parallelized the build
* Initial TREAT tests
* fixed bug in `hibernate-core-jakarta.gradle` related to JPA packaged test bundle handling
This commit is contained in:
Steve Ebersole 2021-06-15 13:43:47 -05:00
parent f02ba820e5
commit e4120234d3
20 changed files with 788 additions and 289 deletions

View File

@ -1,28 +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>.
*/
repositories {
mavenCentral()
jcenter()
}
apply plugin: "groovy"
buildDir = "target"
dependencies {
compile gradleApi()
compile localGroovy()
compile 'org.hibernate.build.gradle:gradle-animalSniffer-plugin:1.0.1.Final'
compile 'org.hibernate.build.gradle:hibernate-matrix-testing:3.0.0.Final'
}
tasks.withType( GroovyCompile ) {
options.encoding = 'UTF-8'
sourceCompatibility = 8
targetCompatibility = 8
}

View File

@ -1,146 +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.build
import org.gradle.api.GradleException
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.testing.Test
import org.hibernate.build.gradle.testing.database.DatabaseProfile
import org.hibernate.build.gradle.testing.database.DatabaseProfilePlugin
import org.hibernate.build.gradle.testing.matrix.MatrixTestingPlugin
/**
* @author Steve Ebersole
*/
class HibernateBuildPlugin implements Plugin<Project> {
private static final Logger log = Logging.getLogger( MatrixTestingPlugin.class);
@Override
void apply(Project project) {
if ( !JavaVersion.current().java8Compatible ) {
throw new GradleException( "Gradle must be run with Java 8" )
}
MavenPublishingExtension publishingExtension = project.extensions.create( "mavenPom", MavenPublishingExtension )
project.afterEvaluate {
applyPublishing( publishingExtension, project )
applyMatrixTestTaskDependencies( project )
}
}
def applyMatrixTestTaskDependencies(Project project) {
final MatrixTestingPlugin matrixTestingPlugin = project.plugins.findPlugin( MatrixTestingPlugin )
if ( matrixTestingPlugin == null ) {
// matrix testing was not applied on this project
return;
}
final DatabaseProfilePlugin databaseProfilePlugin = project.rootProject.plugins.apply( DatabaseProfilePlugin );
if ( databaseProfilePlugin.databaseProfiles == null || databaseProfilePlugin.databaseProfiles.isEmpty() ) {
// no db profiles defined -> nothing to do
return;
}
log.debug( "Project [${project.name}] applied matrix-testing and had db-profiles; checking test task for dependencies" )
// for each db profile, find its execution task and transfer any dependencies from test to it
Test testTask = project.tasks.test
if ( testTask.dependsOn.isEmpty() ) {
return;
}
databaseProfilePlugin.databaseProfiles.each { DatabaseProfile profile ->
log.debug( "db-profile [${profile.name}] on project [${project.name}] : transfering dependencies from test task -> ${testTask.dependsOn}" )
project.tasks.getByPath( "matrix_${profile.name}" ).dependsOn( testTask.dependsOn )
}
}
def applyPublishing(MavenPublishingExtension publishingExtension, Project project) {
PublishingExtension gradlePublishingExtension = project.extensions.getByType( PublishingExtension )
// repos
if ( gradlePublishingExtension.repositories.empty ) {
if ( project.version.endsWith( 'SNAPSHOT' ) ) {
gradlePublishingExtension.repositories.maven {
name 'jboss-snapshots-repository'
url 'https://repository.jboss.org/nexus/content/repositories/snapshots'
}
}
else {
gradlePublishingExtension.repositories.maven {
name 'jboss-releases-repository'
url 'https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/'
}
}
}
// pom
gradlePublishingExtension.publications.withType( MavenPublication ).all { pub->
final boolean applyExtensionValues = publishingExtension.publications == null || publishingExtension.publications.length == 0 || pub in publishingExtension.publications;
pom.withXml {
if ( applyExtensionValues ) {
asNode().appendNode( 'name', publishingExtension.name )
asNode().appendNode( 'description', publishingExtension.description )
Node licenseNode = asNode().appendNode( "licenses" ).appendNode( "license" )
if ( publishingExtension.license == MavenPublishingExtension.License.APACHE2 ) {
licenseNode.appendNode( 'name', 'Apache License, Version 2.0' )
licenseNode.appendNode( 'url', 'http://www.apache.org/licenses/LICENSE-2.0.txt' )
}
else {
licenseNode.appendNode( 'name', 'GNU Lesser General Public License' )
licenseNode.appendNode( 'url', 'http://www.gnu.org/licenses/lgpl-2.1.html' )
licenseNode.appendNode( 'comments', 'See discussion at http://hibernate.org/license for more details.' )
}
licenseNode.appendNode( 'distribution', 'repo' )
}
asNode().children().last() + {
url 'http://hibernate.org'
organization {
name 'Hibernate.org'
url 'http://hibernate.org'
}
issueManagement {
system 'jira'
url 'https://hibernate.atlassian.net/browse/HHH'
}
scm {
url 'http://github.com/hibernate/hibernate-orm'
connection 'scm:git:http://github.com/hibernate/hibernate-orm.git'
developerConnection 'scm:git:git@github.com:hibernate/hibernate-orm.git'
}
developers {
developer {
id 'hibernate-team'
name 'The Hibernate Development Team'
organization 'Hibernate.org'
organizationUrl 'http://hibernate.org'
}
}
}
// TEMPORARY : currently Gradle Publishing feature is exporting dependencies as 'runtime' scope,
// rather than 'compile'; fix that.
if ( asNode().dependencies != null && asNode().dependencies.size() > 0 ) {
asNode().dependencies[0].dependency.each {
it.scope[0].value = 'compile'
}
}
}
}
}
}

View File

@ -1,78 +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.build
import org.gradle.api.publish.maven.MavenPublication
/**
* Defines the information we wish to put into the generated POM for publishing
*
* @author Steve Ebersole
*/
class MavenPublishingExtension {
public static enum License {
APACHE2,
LGPL
}
// The Publications to which the pom information contained here should be supplied.
// By default will apply to all. This is used to limit them.
def MavenPublication[] publications = []
// information for the generated pom
def String name;
def String description;
def License license;
MavenPublication[] getPublications() {
return publications
}
void setPublications(MavenPublication[] publications) {
this.publications = publications
}
def publication(MavenPublication publication) {
publications << publication
}
String getName() {
return name
}
void setName(String name) {
this.name = name
}
String getDescription() {
return description
}
void setDescription(String description) {
this.description = description
}
License getLicense() {
return license
}
void setLicense(License license) {
this.license = license
}
void license(Object license) {
if ( license == null ) {
setLicense( License.LGPL )
}
else if ( license instanceof License ) {
setLicense( license as License )
}
else {
setLicense( License.valueOf( license.toString().toUpperCase( Locale.ENGLISH ) ) )
}
}
}

View File

@ -4,6 +4,8 @@ toolchain.compiler.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOf
toolchain.javadoc.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8
toolchain.launcher.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -Duser.language=en -Duser.country=US -Duser.timezone=UTC -Dfile.encoding=UTF-8
org.gradle.parallel=true
# JDK auto-detection is not quite ready yet in Gradle 6.7.
# On Fedora in particular, if you have the package java-1.8.0-openjdk-headless-1.8.0.265.b01-1.fc32.x86_64 installed,
# Gradle will look for the Java binaries in /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.265.b01-1.fc32.x86_64/bin/java

View File

@ -155,7 +155,7 @@ task copyBundleResources (type: Copy) {
// There are persistence.xml files referencing jar files through their absolute path so we
// have to replace 'hibernate-core/hibernate-core' in the path with 'hibernate-core/hibernate-core-jakarta'
filter { line ->
line.replaceAll( 'hibernate-core/hibernate-core', 'hibernate-core/hibernate-core-jakarta' )
line.replaceAll( 'hibernate-core/', 'hibernate-core-jakarta/' )
}
doFirst {
ext.bundlesTargetDir.mkdirs()

View File

@ -6741,6 +6741,26 @@ public abstract class AbstractEntityPersister
return superDefinedAttribute;
}
}
if ( treatTargetType != null ) {
if ( ! treatTargetType.isTypeOrSuperType( this ) ) {
return null;
}
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {
if ( ! treatTargetType.isTypeOrSuperType( subMappingType ) ) {
continue;
}
final ModelPart subDefinedAttribute = subMappingType.findSubTypesSubPart( name, treatTargetType );
if ( subDefinedAttribute != null ) {
return subDefinedAttribute;
}
}
}
}
else {
if ( subclassMappingTypes != null && !subclassMappingTypes.isEmpty() ) {
for ( EntityMappingType subMappingType : subclassMappingTypes.values() ) {

View File

@ -4112,8 +4112,10 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override
public SqmPath<?> visitTreatedNavigablePath(HqlParser.TreatedNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeManagedTypeReference( ctx.path() );
final String treatTargetName = ctx.dotIdentifierSequence().getText();
final EntityDomainType<?> treatTarget = getCreationContext().getJpaMetamodel().entity( treatTargetName );
final String treatTargetEntityName = getCreationContext().getJpaMetamodel().qualifyImportableName( treatTargetName );
final EntityDomainType<?> treatTarget = getCreationContext().getJpaMetamodel().entity( treatTargetEntityName );
SqmPath<?> result = resolveTreatedPath( sqmPath, treatTarget );

View File

@ -30,6 +30,7 @@ public class StrictJpaComplianceViolation extends SemanticException {
LIMIT_OFFSET_CLAUSE( "use of LIMIT/OFFSET clause" ),
IDENTIFICATION_VARIABLE_NOT_DECLARED_IN_FROM_CLAUSE( "use of an alias not declared in the FROM clause" ),
FQN_ENTITY_NAME( "use of FQN for entity name" ),
IMPLICIT_TREAT( "use of implicit treat" ),
;
private final String description;

View File

@ -324,6 +324,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
private static final Logger log = Logger.getLogger( BaseSqmToSqlAstConverter.class );
private final SqlAstCreationContext creationContext;
private final boolean jpaQueryComplianceEnabled;
private final SqmStatement<?> statement;
private final QueryOptions queryOptions;
@ -369,6 +370,12 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
super( creationContext.getServiceRegistry() );
this.creationContext = creationContext;
this.jpaQueryComplianceEnabled = creationContext
.getSessionFactory()
.getSessionFactoryOptions()
.getJpaCompliance()
.isJpaQueryComplianceEnabled();
this.statement = statement;
if ( statement instanceof SqmSelectStatement<?> ) {
@ -681,8 +688,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
.getRoot()
.get( versionMapping.getPartName() ),
this,
this
).getColumnReferences();
this,
jpaQueryComplianceEnabled ).getColumnReferences();
assert targetColumnReferences.size() == 1;
final ColumnReference versionColumn = targetColumnReferences.get( 0 );
@ -959,8 +966,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
(SqmBasicValuedSimplePath<?>) sqmStatement.getTarget()
.get( versionAttributeName ),
this,
this
).getColumnReferences();
this,
jpaQueryComplianceEnabled ).getColumnReferences();
assert targetColumnReferences.size() == 1;
insertStatement.addTargetColumnReferences( targetColumnReferences );
@ -2181,7 +2188,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Expression visitBasicValuedPath(SqmBasicValuedSimplePath<?> sqmPath) {
BasicValuedPathInterpretation<?> path = BasicValuedPathInterpretation.from( sqmPath, this, this );
BasicValuedPathInterpretation<?> path = BasicValuedPathInterpretation.from( sqmPath, this, this, jpaQueryComplianceEnabled );
if ( isDuration( sqmPath.getNodeType() ) ) {
@ -2244,7 +2251,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public SqmPathInterpretation<?> visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath<?> sqmPath) {
return EmbeddableValuedPathInterpretation.from( sqmPath, this, this );
return EmbeddableValuedPathInterpretation.from( sqmPath, this, this, jpaQueryComplianceEnabled );
}
@Override

View File

@ -10,10 +10,16 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -34,15 +40,41 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
public static <T> BasicValuedPathInterpretation<T> from(
SqmBasicValuedSimplePath<T> sqmPath,
SqlAstCreationState sqlAstCreationState,
SemanticQueryWalker sqmWalker) {
SemanticQueryWalker sqmWalker,
boolean jpaQueryComplianceEnabled) {
TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( sqmPath.getLhs().getNavigablePath() );
EntityMappingType treatTarget = null;
if ( jpaQueryComplianceEnabled ) {
if ( sqmPath.getLhs() instanceof SqmTreatedPath ) {
final EntityDomainType treatTargetDomainType = ( (SqmTreatedPath) sqmPath.getLhs() ).getTreatTarget();
final MappingMetamodel domainModel = sqlAstCreationState.getCreationContext().getDomainModel();
treatTarget = domainModel.findEntityDescriptor( treatTargetDomainType.getHibernateEntityName() );
}
else if ( sqmPath.getLhs().getNodeType() instanceof EntityDomainType ) {
final EntityDomainType entityDomainType = (EntityDomainType) sqmPath.getLhs().getNodeType();
final MappingMetamodel domainModel = sqlAstCreationState.getCreationContext().getDomainModel();
treatTarget = domainModel.findEntityDescriptor( entityDomainType.getHibernateEntityName() );
}
}
final BasicValuedModelPart mapping = (BasicValuedModelPart) tableGroup.getModelPart().findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
null
treatTarget
);
if ( mapping == null ) {
if ( jpaQueryComplianceEnabled ) {
// to get the better error, see if we got nothing because of treat handling
final ModelPart subPart = tableGroup.getModelPart().findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
null
);
if ( subPart != null ) {
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.IMPLICIT_TREAT );
}
}
throw new SemanticException( "`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part" );
}

View File

@ -10,10 +10,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -33,13 +37,28 @@ public class EmbeddableValuedPathInterpretation<T> extends AbstractSqmPathInterp
public static <T> EmbeddableValuedPathInterpretation<T> from(
SqmEmbeddedValuedSimplePath<T> sqmPath,
SqmToSqlAstConverter converter,
SemanticQueryWalker sqmWalker) {
TableGroup tableGroup = converter.getFromClauseAccess()
.findTableGroup( sqmPath.getLhs().getNavigablePath() );
SemanticQueryWalker sqmWalker,
boolean jpaQueryComplianceEnabled) {
TableGroup tableGroup = converter.getFromClauseAccess().findTableGroup( sqmPath.getLhs().getNavigablePath() );
EntityMappingType treatTarget = null;
if ( jpaQueryComplianceEnabled ) {
if ( sqmPath.getLhs() instanceof SqmTreatedPath ) {
final EntityDomainType treatTargetDomainType = ( (SqmTreatedPath) sqmPath.getLhs() ).getTreatTarget();
final MappingMetamodel domainModel = converter.getCreationContext().getDomainModel();
treatTarget = domainModel.findEntityDescriptor( treatTargetDomainType.getHibernateEntityName() );
}
else if ( sqmPath.getLhs().getNodeType() instanceof EntityDomainType ) {
final EntityDomainType entityDomainType = (EntityDomainType) sqmPath.getLhs().getNodeType();
final MappingMetamodel domainModel = converter.getCreationContext().getDomainModel();
treatTarget = domainModel.findEntityDescriptor( entityDomainType.getHibernateEntityName() );
}
}
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) tableGroup.getModelPart().findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
null
treatTarget
);
return new EmbeddableValuedPathInterpretation<>(

View File

@ -87,6 +87,19 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
this.alias = alias;
}
/**
* Intended for use with {@link SqmTreatedRoot} -> {@link SqmRoot}
*/
protected AbstractSqmFrom(
NavigablePath navigablePath,
EntityDomainType<T> entityType,
String alias,
NodeBuilder nodeBuilder) {
super( navigablePath, entityType, null, nodeBuilder );
this.alias = alias;
}
/**
* Intended for use with {@link SqmCorrelatedRootJoin} through {@link SqmRoot}
*/

View File

@ -7,6 +7,7 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.SqmPathSource;
/**
* @author Steve Ebersole
@ -14,6 +15,11 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
public interface SqmTreatedPath<T, S extends T> extends SqmPathWrapper<T, S> {
EntityDomainType<S> getTreatTarget();
@Override
default SqmPathSource<S> getNodeType() {
return getTreatTarget();
}
@Override
SqmPath<T> getWrappedPath();
}

View File

@ -7,8 +7,13 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.tree.from.SqmRoot;
/**
@ -18,12 +23,13 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
private final SqmRoot<T> wrappedPath;
private final EntityDomainType<S> treatTarget;
@SuppressWarnings({ "unchecked", "rawtypes" })
public SqmTreatedRoot(
SqmRoot<T> wrappedPath,
EntityDomainType<S> treatTarget,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
wrappedPath.getNavigablePath(),
(EntityDomainType) wrappedPath.getReferencedPathSource(),
null,
nodeBuilder
@ -49,12 +55,11 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
@Override
public EntityDomainType<S> getReferencedPathSource() {
//noinspection unchecked
return (EntityDomainType) wrappedPath.getReferencedPathSource();
return getManagedType();
}
@Override
public SqmPath getLhs() {
public SqmPath<?> getLhs() {
return wrappedPath.getLhs();
}
@ -62,4 +67,30 @@ public class SqmTreatedRoot<T, S extends T> extends SqmRoot<S> implements SqmTre
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitTreatedPath( this );
}
@Override
public SemanticPathPart resolvePathPart(
String name,
boolean isTerminal,
SqmCreationState creationState) {
final NavigablePath subNavPath = getNavigablePath().append( name );
return creationState.getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
subNavPath,
snp -> {
final SqmPathSource<?> subSource;
if ( creationState.getCreationOptions().useStrictJpaCompliance() ) {
subSource = getManagedType().findSubPathSource( name );
}
else {
subSource = treatTarget.findSubPathSource( name );
}
if ( subSource == null ) {
throw UnknownPathException.unknownSubPath( this, name );
}
return subSource.createSqmPath( this );
}
);
}
}

View File

@ -44,6 +44,15 @@ public class SqmRoot<E> extends AbstractSqmFrom<E,E> implements JpaRoot<E>, Doma
super( navigablePath, referencedNavigable, nodeBuilder );
}
public SqmRoot(
NavigablePath navigablePath,
EntityDomainType<E> entityType,
String alias,
NodeBuilder nodeBuilder) {
super( navigablePath, entityType, alias, nodeBuilder );
}
@Override
public SqmPath<?> getLhs() {
// a root has no LHS

View File

@ -0,0 +1,147 @@
/*
* 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.test.query.hql.treat;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.NotImplementedYet;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = @Setting( name = AvailableSettings.JPA_QUERY_COMPLIANCE, value = "true" )
)
@DomainModel( annotatedClasses = { DiscriminatedTreatSmokeTesting.Volume.class, DiscriminatedTreatSmokeTesting.ExtendedVolume.class } )
@SessionFactory
public class DiscriminatedTreatSmokeTesting {
@Test
public void simpleImplicitTreatTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where v.strategy = 'noneya'";
try {
session.createQuery( qryString, DiscriminatedTreatSmokeTesting.Volume.class ).list();
fail( "This should fail with strict compliance enabled" );
}
catch (IllegalArgumentException e) {
assertThat( e.getCause() ).isInstanceOf( StrictJpaComplianceViolation.class );
final StrictJpaComplianceViolation violation = (StrictJpaComplianceViolation) e.getCause();
assertThat( violation.getType() ).isEqualTo( StrictJpaComplianceViolation.Type.IMPLICIT_TREAT );
}
}
);
}
@Test
public void simpleTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where treat(v as ExtendedVolume).strategy = 'noneya'";
final List<Volume> results = session.createQuery( qryString, Volume.class ).list();
assertThat( results ).hasSize( 1 );
}
);
}
@Test
public void simpleDisjunctionWithTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where treat(v as ExtendedVolume).strategy = 'noneya'";
final List<Volume> results = session.createQuery( qryString, Volume.class ).list();
assertThat( results ).hasSize( 1 );
}
);
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
final Volume volume = new Volume( 1, "abc" );
final ExtendedVolume extendedVolume = new ExtendedVolume( 2, "def", "noneya" );
scope.inTransaction(
(session) -> {
session.persist( volume );
session.persist( extendedVolume );
}
);
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> session.createQuery( "delete Volume" ).executeUpdate()
);
}
@Entity( name = "Volume" )
@Table( name = "treated_volume" )
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name = "type" )
@DiscriminatorValue( "V" )
public static class Volume {
@Id
private Integer id;
private String label;
public Volume() {
}
public Volume(Integer id, String label) {
this.id = id;
this.label = label;
}
}
@Entity( name = "ExtendedVolume" )
@Table( name = "treated_extended_volume" )
@DiscriminatorValue( "E" )
public static class ExtendedVolume extends Volume {
private String strategy;
public ExtendedVolume() {
}
public ExtendedVolume(Integer id, String label, String strategy) {
super( id, label );
this.strategy = strategy;
}
}
}

View File

@ -0,0 +1,145 @@
/*
* 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.test.query.hql.treat;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.NotImplementedYet;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = @Setting( name = AvailableSettings.JPA_QUERY_COMPLIANCE, value = "true" )
)
@DomainModel( annotatedClasses = { DiscriminatedTreatSqmSmokeTesting.Volume.class, DiscriminatedTreatSqmSmokeTesting.ExtendedVolume.class } )
@SessionFactory
public class DiscriminatedTreatSqmSmokeTesting {
@Test
public void simpleImplicitTreatTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where v.strategy = 'noneya'";
try {
session.createQuery( qryString, Volume.class ).list();
fail( "This should fail with strict compliance enabled" );
}
catch (IllegalArgumentException e) {
assertThat( e.getCause() ).isInstanceOf( StrictJpaComplianceViolation.class );
final StrictJpaComplianceViolation violation = (StrictJpaComplianceViolation) e.getCause();
assertThat( violation.getType() ).isEqualTo( StrictJpaComplianceViolation.Type.IMPLICIT_TREAT );
}
}
);
}
@Test
public void simpleTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where treat(v as ExtendedVolume).strategy = 'noneya'";
final List<Volume> results = session.createQuery( qryString, Volume.class ).list();
assertThat( results ).hasSize( 1 );
}
);
}
@Test
public void simpleDisjunctionWithTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where treat(v as ExtendedVolume).strategy = 'noneya'";
final List<Volume> results = session.createQuery( qryString, Volume.class ).list();
assertThat( results ).hasSize( 1 );
}
);
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
final Volume volume = new Volume( 1, "abc" );
final ExtendedVolume extendedVolume = new ExtendedVolume( 2, "def", "noneya" );
scope.inTransaction(
(session) -> {
session.persist( volume );
session.persist( extendedVolume );
}
);
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> session.createQuery( "delete Volume" ).executeUpdate()
);
}
@Entity( name = "Volume" )
@Table( name = "treated_volume" )
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name = "type" )
@DiscriminatorValue( "V" )
public static class Volume {
@Id
private Integer id;
private String label;
public Volume() {
}
public Volume(Integer id, String label) {
this.id = id;
this.label = label;
}
}
@Entity( name = "ExtendedVolume" )
@Table( name = "treated_extended_volume" )
@DiscriminatorValue( "E" )
public static class ExtendedVolume extends Volume {
private String strategy;
public ExtendedVolume() {
}
public ExtendedVolume(Integer id, String label, String strategy) {
super( id, label );
this.strategy = strategy;
}
}
}

View File

@ -0,0 +1,129 @@
/*
* 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.test.query.hql.treat;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = @Setting( name = AvailableSettings.JPA_QUERY_COMPLIANCE, value = "true" )
)
@DomainModel( annotatedClasses = { JoinedTreatSmokeTesting.Volume.class, JoinedTreatSmokeTesting.ExtendedVolume.class } )
@SessionFactory
public class JoinedTreatSmokeTesting {
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
final Volume volume = new Volume( 1, "abc" );
final ExtendedVolume extendedVolume = new ExtendedVolume( 2, "def", "noneya" );
scope.inTransaction(
(session) -> {
session.persist( volume );
session.persist( extendedVolume );
}
);
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> session.createQuery( "delete Volume" ).executeUpdate()
);
}
@Test
public void simpleImplicitTreatTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where v.strategy = 'noneya'";
try {
session.createQuery( qryString, Volume.class ).list();
fail( "This should fail with strict compliance enabled" );
}
catch (IllegalArgumentException e) {
assertThat( e.getCause() ).isInstanceOf( StrictJpaComplianceViolation.class );
final StrictJpaComplianceViolation violation = (StrictJpaComplianceViolation) e.getCause();
assertThat( violation.getType() ).isEqualTo( StrictJpaComplianceViolation.Type.IMPLICIT_TREAT );
}
}
);
}
@Test
public void simpleTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final List<Volume> results = session
.createQuery( "select v from Volume v where treat(v as ExtendedVolume).strategy = 'noneya'", Volume.class )
.list();
assertThat( results ).hasSize( 1 );
}
);
}
@Entity( name = "Volume" )
@Table( name = "treated_volume" )
@Inheritance( strategy = InheritanceType.JOINED )
@DiscriminatorColumn( name = "type" )
@DiscriminatorValue( "V" )
public static class Volume {
@Id
private Integer id;
private String label;
public Volume() {
}
public Volume(Integer id, String label) {
this.id = id;
this.label = label;
}
}
@Entity( name = "ExtendedVolume" )
@Table( name = "treated_extended_volume" )
@DiscriminatorValue( "E" )
public static class ExtendedVolume extends Volume {
private String strategy;
public ExtendedVolume() {
}
public ExtendedVolume(Integer id, String label, String strategy) {
super( id, label );
this.strategy = strategy;
}
}
}

View File

@ -0,0 +1,126 @@
/*
* 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.test.query.hql.treat;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@ServiceRegistry(
settings = @Setting( name = AvailableSettings.JPA_QUERY_COMPLIANCE, value = "true" )
)
@DomainModel( annotatedClasses = { PerClassTreatSmokeTesting.Volume.class, PerClassTreatSmokeTesting.ExtendedVolume.class } )
@SessionFactory
public class PerClassTreatSmokeTesting {
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
final Volume volume = new Volume( 1, "abc" );
final ExtendedVolume extendedVolume = new ExtendedVolume( 2, "def", "noneya" );
scope.inTransaction(
(session) -> {
session.persist( volume );
session.persist( extendedVolume );
}
);
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> session.createQuery( "delete Volume" ).executeUpdate()
);
}
@Test
public void simpleImplicitTreatTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final String qryString = "select v " +
"from Volume v " +
"where v.strategy = 'noneya'";
try {
session.createQuery( qryString, Volume.class ).list();
fail( "This should fail with strict compliance enabled" );
}
catch (IllegalArgumentException e) {
assertThat( e.getCause() ).isInstanceOf( StrictJpaComplianceViolation.class );
final StrictJpaComplianceViolation violation = (StrictJpaComplianceViolation) e.getCause();
assertThat( violation.getType() ).isEqualTo( StrictJpaComplianceViolation.Type.IMPLICIT_TREAT );
}
}
);
}
@Test
public void simpleTreatedRootTest(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
final List<Volume> results = session
.createQuery( "select v from Volume v where treat(v as ExtendedVolume).strategy = 'noneya'", Volume.class )
.list();
assertThat( results ).hasSize( 1 );
}
);
}
@Entity( name = "Volume" )
@Table( name = "treated_volume" )
@Inheritance( strategy = InheritanceType.TABLE_PER_CLASS )
public static class Volume {
@Id
private Integer id;
private String label;
public Volume() {
}
public Volume(Integer id, String label) {
this.id = id;
this.label = label;
}
}
@Entity( name = "ExtendedVolume" )
@Table( name = "treated_extended_volume" )
public static class ExtendedVolume extends Volume {
private String strategy;
public ExtendedVolume() {
}
public ExtendedVolume(Integer id, String label, String strategy) {
super( id, label );
this.strategy = strategy;
}
}
}

View File

@ -12,6 +12,7 @@ apply from: rootProject.file( 'gradle/base-information.gradle' )
apply plugin: 'idea'
apply plugin: 'distribution'
//apply plugin: 'java-library-distribution'
idea.module {
@ -21,6 +22,47 @@ final File documentationDir = mkdir( "${project.buildDir}/documentation" )
final File projectTemplateStagingDir = mkdir( "${project.buildDir}/projectTemplate" )
configurations {
core
// testing
envers
agroal
c3p0
hikaricp
proxool
vibur
jcache
jpamodelgen
coreJakarta
// testingJakarta
enversJakarta
jpamodelgenJakarta
}
dependencies {
core project( ':hibernate-core' )
// testing project( ':hibernate-testing' )
envers project( ':hibernate-envers' )
agroal project( ':hibernate-agroal' )
c3p0 project( ':hibernate-c3p0' )
hikaricp project( ':hibernate-hikaricp' )
proxool project( ':hibernate-proxool' )
vibur project( ':hibernate-vibur' )
jcache project( ':hibernate-jcache' )
jpamodelgen project( ':hibernate-jpamodelgen' )
coreJakarta project( ':hibernate-core-jakarta' )
// testingJakarta project( ':hibernate-testing-jakarta' )
enversJakarta project( ':hibernate-envers-jakarta' )
jpamodelgenJakarta project( ':hibernate-jpamodelgen-jakarta' )
}
/**
* Assembles all documentation into the {buildDir}/documentation directory.
*
@ -116,8 +158,7 @@ distributions {
from rootProject.file( 'hibernate_logo.gif' )
into('lib/required') {
from ( parent.project( 'hibernate-core' ).configurations.default +
parent.project( 'hibernate-core' ).configurations.default.allArtifacts.files )
from configurations.core
}
// todo (6.0) - add back
@ -137,29 +178,50 @@ distributions {
// }
into( 'lib/jpa-metamodel-generator' ) {
from ( parent.project( 'hibernate-jpamodelgen' ).configurations.default +
parent.project( 'hibernate-jpamodelgen' ).configurations.default.allArtifacts.files )
from( configurations.jpamodelgen - configurations.core )
}
into( 'lib/envers' ) {
from(
( parent.project( 'hibernate-envers' ).configurations.default.allArtifacts.files +
parent.project( 'hibernate-envers' ).configurations.default ) -
( parent.project( 'hibernate-core' ).configurations.default.allArtifacts.files +
parent.project( 'hibernate-core' ).configurations.default )
)
from( configurations.envers - configurations.core )
}
// into( 'lib/testing' ) {
// from( configurations.testing - configurations.core )
// }
[ 'hibernate-agroal', 'hibernate-c3p0', 'hibernate-hikaricp', 'hibernate-jcache', 'hibernate-proxool', 'hibernate-vibur' ].each { feature ->
final String shortName = feature.substring( 'hibernate-'.length() )
owner.into('lib/optional/' + shortName) {
from(
( parent.project( feature ).configurations.default.files +
parent.project( feature ).configurations.default.allArtifacts.files ) -
( parent.project( 'hibernate-core' ).configurations.default.files +
parent.project( 'hibernate-core' ).configurations.default.allArtifacts.files )
)
into( 'lib/optional' ) {
into( 'agroal' ) {
from( configurations.agroal - configurations.core )
}
into( 'c3p0' ) {
from( configurations.c3p0 - configurations.core )
}
into( 'hikaricp' ) {
from( configurations.hikaricp - configurations.core )
}
into( 'jcache' ) {
from( configurations.jcache - configurations.core )
}
into( 'proxool' ) {
from( configurations.proxool - configurations.core )
}
into( 'vibur' ) {
from( configurations.vibur - configurations.core )
}
}
into( 'lib/jakarta' ) {
into( 'required' ) {
from configurations.coreJakarta
}
// into( 'testing' ) {
// from( configurations.testingJakarta - configurations.coreJakarta )
// }
into( 'envers' ) {
from( configurations.enversJakarta - configurations.coreJakarta )
}
into( 'jpa-metamodel-generator' ) {
from( configurations.jpamodelgenJakarta - configurations.coreJakarta )
}
}