* 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:
parent
f02ba820e5
commit
e4120234d3
|
@ -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
|
||||
}
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 ) ) )
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
|
||||
|
|
|
@ -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<>(
|
||||
|
|
|
@ -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}
|
||||
*/
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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 )
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue