mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
initial working dynamic instantiation support;
cleanup
This commit is contained in:
parent
055ce0c542
commit
5631a702a7
@ -14,12 +14,14 @@
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
@ -41,6 +43,7 @@
|
|||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.type.SerializationException;
|
import org.hibernate.type.SerializationException;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,6 +67,8 @@ public class MetadataSources implements Serializable {
|
|||||||
private LinkedHashSet<String> annotatedClassNames = new LinkedHashSet<>();
|
private LinkedHashSet<String> annotatedClassNames = new LinkedHashSet<>();
|
||||||
private LinkedHashSet<String> annotatedPackages = new LinkedHashSet<>();
|
private LinkedHashSet<String> annotatedPackages = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
private Map<String,Class<?>> extraQueryImports;
|
||||||
|
|
||||||
public MetadataSources() {
|
public MetadataSources() {
|
||||||
this( new BootstrapServiceRegistryBuilder().build() );
|
this( new BootstrapServiceRegistryBuilder().build() );
|
||||||
}
|
}
|
||||||
@ -111,6 +116,10 @@ public Collection<String> getAnnotatedClassNames() {
|
|||||||
return annotatedClassNames;
|
return annotatedClassNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String,Class<?>> getExtraQueryImports() {
|
||||||
|
return extraQueryImports;
|
||||||
|
}
|
||||||
|
|
||||||
public ServiceRegistry getServiceRegistry() {
|
public ServiceRegistry getServiceRegistry() {
|
||||||
return serviceRegistry;
|
return serviceRegistry;
|
||||||
}
|
}
|
||||||
@ -196,6 +205,16 @@ public MetadataSources addAnnotatedClass(Class annotatedClass) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Var-arg form of {@link #addAnnotatedClass}
|
||||||
|
*/
|
||||||
|
public MetadataSources addAnnotatedClasses(Class<?>... annotatedClasses) {
|
||||||
|
if ( annotatedClasses != null && annotatedClasses.length > 0 ) {
|
||||||
|
Collections.addAll( this.annotatedClasses, annotatedClasses );
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read metadata from the annotations attached to the given class. The important
|
* Read metadata from the annotations attached to the given class. The important
|
||||||
* distinction here is that the {@link Class} will not be accessed until later
|
* distinction here is that the {@link Class} will not be accessed until later
|
||||||
@ -210,6 +229,26 @@ public MetadataSources addAnnotatedClassName(String annotatedClassName) {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Var-arg form of {@link #addAnnotatedClassName}
|
||||||
|
*/
|
||||||
|
public MetadataSources addAnnotatedClassNames(String... annotatedClassNames) {
|
||||||
|
if ( annotatedClassNames != null && annotatedClassNames.length > 0 ) {
|
||||||
|
Collections.addAll( this.annotatedClassNames, annotatedClassNames );
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetadataSources addQueryImport(String importedName, Class<?> target) {
|
||||||
|
if ( extraQueryImports == null ) {
|
||||||
|
extraQueryImports = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
extraQueryImports.put( importedName, target );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read package-level metadata.
|
* Read package-level metadata.
|
||||||
*
|
*
|
||||||
|
@ -30,6 +30,7 @@ public class ManagedResourcesImpl implements ManagedResources {
|
|||||||
private Set<String> annotatedClassNames = new LinkedHashSet<>();
|
private Set<String> annotatedClassNames = new LinkedHashSet<>();
|
||||||
private Set<String> annotatedPackageNames = new LinkedHashSet<>();
|
private Set<String> annotatedPackageNames = new LinkedHashSet<>();
|
||||||
private List<Binding> mappingFileBindings = new ArrayList<>();
|
private List<Binding> mappingFileBindings = new ArrayList<>();
|
||||||
|
private Map<String, Class<?>> extraQueryImports;
|
||||||
|
|
||||||
public static ManagedResourcesImpl baseline(MetadataSources sources, BootstrapContext bootstrapContext) {
|
public static ManagedResourcesImpl baseline(MetadataSources sources, BootstrapContext bootstrapContext) {
|
||||||
final ManagedResourcesImpl impl = new ManagedResourcesImpl();
|
final ManagedResourcesImpl impl = new ManagedResourcesImpl();
|
||||||
@ -38,6 +39,7 @@ public static ManagedResourcesImpl baseline(MetadataSources sources, BootstrapCo
|
|||||||
impl.annotatedClassNames.addAll( sources.getAnnotatedClassNames() );
|
impl.annotatedClassNames.addAll( sources.getAnnotatedClassNames() );
|
||||||
impl.annotatedPackageNames.addAll( sources.getAnnotatedPackages() );
|
impl.annotatedPackageNames.addAll( sources.getAnnotatedPackages() );
|
||||||
impl.mappingFileBindings.addAll( sources.getXmlBindings() );
|
impl.mappingFileBindings.addAll( sources.getXmlBindings() );
|
||||||
|
impl.extraQueryImports = sources.getExtraQueryImports();
|
||||||
return impl;
|
return impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +71,11 @@ public Collection<Binding> getXmlMappingBindings() {
|
|||||||
return Collections.unmodifiableList( mappingFileBindings );
|
return Collections.unmodifiableList( mappingFileBindings );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Class<?>> getExtraQueryImports() {
|
||||||
|
return extraQueryImports;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// package private
|
// package private
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
package org.hibernate.boot.model.process.spi;
|
package org.hibernate.boot.model.process.spi;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.boot.AttributeConverterInfo;
|
import org.hibernate.boot.AttributeConverterInfo;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
@ -66,4 +68,6 @@ public interface ManagedResources {
|
|||||||
* @return The list of bindings for all known XML mapping files.
|
* @return The list of bindings for all known XML mapping files.
|
||||||
*/
|
*/
|
||||||
Collection<Binding> getXmlMappingBindings();
|
Collection<Binding> getXmlMappingBindings();
|
||||||
|
|
||||||
|
Map<String,Class<?>> getExtraQueryImports();
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
@ -304,9 +305,24 @@ public void finishUp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyExtraQueryImports( managedResources, metadataCollector );
|
||||||
|
|
||||||
return metadataCollector.buildMetadataInstance( rootMetadataBuildingContext );
|
return metadataCollector.buildMetadataInstance( rootMetadataBuildingContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void applyExtraQueryImports(
|
||||||
|
ManagedResources managedResources,
|
||||||
|
InFlightMetadataCollectorImpl metadataCollector) {
|
||||||
|
final Map<String, Class<?>> extraQueryImports = managedResources.getExtraQueryImports();
|
||||||
|
if ( extraQueryImports == null || extraQueryImports.isEmpty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( Map.Entry<String, Class<?>> entry : extraQueryImports.entrySet() ) {
|
||||||
|
metadataCollector.addImport( entry.getKey(), entry.getValue().getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// todo (7.0) : buildJandexInitializer
|
// todo (7.0) : buildJandexInitializer
|
||||||
// private static JandexInitManager buildJandexInitializer(
|
// private static JandexInitManager buildJandexInitializer(
|
||||||
// MetadataBuildingOptions options,
|
// MetadataBuildingOptions options,
|
||||||
|
@ -81,6 +81,8 @@ default ServiceRegistry getServiceRegistry() {
|
|||||||
|
|
||||||
void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action);
|
void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action);
|
||||||
|
|
||||||
|
String qualifyImportableName(String queryName);
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Covariant returns
|
// Covariant returns
|
||||||
|
@ -269,6 +269,11 @@ public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Clas
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String qualifyImportableName(String queryName) {
|
||||||
|
return resolveImportedName( queryName );
|
||||||
|
}
|
||||||
|
|
||||||
private String resolveImportedName(String name) {
|
private String resolveImportedName(String name) {
|
||||||
String result = nameToImportNameMap.get( name );
|
String result = nameToImportNameMap.get( name );
|
||||||
if ( result == null ) {
|
if ( result == null ) {
|
||||||
|
@ -238,9 +238,4 @@ public String getAlias() {
|
|||||||
public NodeBuilder nodeBuilder() {
|
public NodeBuilder nodeBuilder() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmExpressable getExpressableType() {
|
|
||||||
return expressableType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -570,11 +570,7 @@ else if ( ctx.dynamicInstantiationTarget().LIST() != null ) {
|
|||||||
else {
|
else {
|
||||||
final String className = ctx.dynamicInstantiationTarget().dotIdentifierSequence().getText();
|
final String className = ctx.dynamicInstantiationTarget().dotIdentifierSequence().getText();
|
||||||
try {
|
try {
|
||||||
final Class<?> targetJavaType = classForName( className );
|
final JavaTypeDescriptor jtd = resolveInstantiationTargetJtd( className );
|
||||||
final JavaTypeDescriptor jtd = creationContext.getJpaMetamodel()
|
|
||||||
.getTypeConfiguration()
|
|
||||||
.getJavaTypeDescriptorRegistry()
|
|
||||||
.resolveDescriptor( targetJavaType );
|
|
||||||
dynamicInstantiation = SqmDynamicInstantiation.forClassInstantiation(
|
dynamicInstantiation = SqmDynamicInstantiation.forClassInstantiation(
|
||||||
jtd,
|
jtd,
|
||||||
creationContext.getNodeBuilder()
|
creationContext.getNodeBuilder()
|
||||||
@ -592,6 +588,14 @@ else if ( ctx.dynamicInstantiationTarget().LIST() != null ) {
|
|||||||
return dynamicInstantiation;
|
return dynamicInstantiation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JavaTypeDescriptor resolveInstantiationTargetJtd(String className) {
|
||||||
|
final Class<?> targetJavaType = classForName( creationContext.getJpaMetamodel().qualifyImportableName( className ) );
|
||||||
|
return creationContext.getJpaMetamodel()
|
||||||
|
.getTypeConfiguration()
|
||||||
|
.getJavaTypeDescriptorRegistry()
|
||||||
|
.resolveDescriptor( targetJavaType );
|
||||||
|
}
|
||||||
|
|
||||||
private Class classForName(String className) {
|
private Class classForName(String className) {
|
||||||
return creationContext.getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
|
return creationContext.getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||||
import org.hibernate.internal.util.collections.Stack;
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
import org.hibernate.internal.util.collections.StandardStack;
|
import org.hibernate.internal.util.collections.StandardStack;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
@ -35,12 +35,12 @@
|
|||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.function.SqmFunction;
|
import org.hibernate.query.sqm.function.SqmFunction;
|
||||||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||||
|
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
||||||
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
|
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess;
|
import org.hibernate.query.sqm.spi.JdbcParameterBySqmParameterAccess;
|
||||||
import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
|
import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
|
||||||
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
|
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqlAstQuerySpecProcessingStateImpl;
|
import org.hibernate.query.sqm.sql.internal.SqlAstQuerySpecProcessingStateImpl;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmExpressionInterpretation;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation;
|
import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
||||||
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
||||||
@ -614,8 +614,12 @@ public SqmPathInterpretation<?> visitPluralValuedPath(SqmPluralValuedSimplePath
|
|||||||
// General expressions
|
// General expressions
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressionInterpretation visitLiteral(SqmLiteral literal) {
|
public Expression visitLiteral(SqmLiteral literal) {
|
||||||
return literal;
|
return new QueryLiteral(
|
||||||
|
literal.getLiteralValue(),
|
||||||
|
(BasicValuedMapping) SqmMappingModelHelper.resolveMappingModelExpressable( literal, this ),
|
||||||
|
getCurrentClauseStack().getCurrent()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<SqmParameter,List<JdbcParameter>> jdbcParamsBySqmParam = new IdentityHashMap<>();
|
private final Map<SqmParameter,List<JdbcParameter>> jdbcParamsBySqmParam = new IdentityHashMap<>();
|
||||||
@ -627,12 +631,12 @@ public Map<SqmParameter, List<JdbcParameter>> getJdbcParamsBySqmParam() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressionInterpretation visitNamedParameterExpression(SqmNamedParameter expression) {
|
public Expression visitNamedParameterExpression(SqmNamedParameter expression) {
|
||||||
return consumeSqmParameter( expression );
|
return consumeSqmParameter( expression );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private SqmExpressionInterpretation consumeSqmParameter(SqmParameter sqmParameter) {
|
private Expression consumeSqmParameter(SqmParameter sqmParameter) {
|
||||||
final MappingModelExpressable valueMapping = determineValueMapping( sqmParameter );
|
final MappingModelExpressable valueMapping = determineValueMapping( sqmParameter );
|
||||||
final List<JdbcParameter> jdbcParametersForSqm = new ArrayList<>();
|
final List<JdbcParameter> jdbcParametersForSqm = new ArrayList<>();
|
||||||
|
|
||||||
@ -1242,7 +1246,7 @@ public CaseSearchedExpression visitSearchedCaseExpression(SqmCaseSearched<?> exp
|
|||||||
public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) {
|
public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) {
|
||||||
return new QueryLiteral(
|
return new QueryLiteral(
|
||||||
sqmEnumLiteral.getEnumValue(),
|
sqmEnumLiteral.getEnumValue(),
|
||||||
determineValueMapping( sqmEnumLiteral ),
|
(BasicValuedMapping) determineValueMapping( sqmEnumLiteral ),
|
||||||
getCurrentClauseStack().getCurrent()
|
getCurrentClauseStack().getCurrent()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1251,7 +1255,7 @@ public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) {
|
|||||||
public Object visitFieldLiteral(SqmFieldLiteral sqmFieldLiteral) {
|
public Object visitFieldLiteral(SqmFieldLiteral sqmFieldLiteral) {
|
||||||
return new QueryLiteral(
|
return new QueryLiteral(
|
||||||
sqmFieldLiteral.getValue(),
|
sqmFieldLiteral.getValue(),
|
||||||
determineValueMapping( sqmFieldLiteral ),
|
(BasicValuedMapping) determineValueMapping( sqmFieldLiteral ),
|
||||||
getCurrentClauseStack().getCurrent()
|
getCurrentClauseStack().getCurrent()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1322,11 +1326,7 @@ public ComparisonPredicate visitComparisonPredicate(SqmComparisonPredicate predi
|
|||||||
|
|
||||||
final Expression lhs;
|
final Expression lhs;
|
||||||
try {
|
try {
|
||||||
lhs = ( (SqmExpressionInterpretation) predicate.getLeftHandExpression().accept( this ) ).toSqlExpression(
|
lhs = (Expression) predicate.getLeftHandExpression().accept( this );
|
||||||
getCurrentClauseStack().getCurrent(),
|
|
||||||
this,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
inferableTypeAccessStack.pop();
|
inferableTypeAccessStack.pop();
|
||||||
@ -1336,11 +1336,7 @@ public ComparisonPredicate visitComparisonPredicate(SqmComparisonPredicate predi
|
|||||||
|
|
||||||
final Expression rhs;
|
final Expression rhs;
|
||||||
try {
|
try {
|
||||||
rhs = ( (SqmExpressionInterpretation) predicate.getRightHandExpression().accept( this ) ).toSqlExpression(
|
rhs = (Expression) predicate.getRightHandExpression().accept( this );
|
||||||
getCurrentClauseStack().getCurrent(),
|
|
||||||
this,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
inferableTypeAccessStack.pop();
|
inferableTypeAccessStack.pop();
|
||||||
@ -1472,13 +1468,7 @@ public InListPredicate visitInListPredicate(SqmInListPredicate<?> predicate) {
|
|||||||
domainParameterXref.addExpansion( domainParam, sqmParameter, sqmParamToConsume );
|
domainParameterXref.addExpansion( domainParam, sqmParameter, sqmParamToConsume );
|
||||||
}
|
}
|
||||||
|
|
||||||
inListPredicate.addExpression(
|
inListPredicate.addExpression( consumeSqmParameter( sqmParamToConsume ) );
|
||||||
consumeSqmParameter( sqmParamToConsume ).toSqlExpression(
|
|
||||||
getCurrentClauseStack().getCurrent(),
|
|
||||||
this,
|
|
||||||
this
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -6,8 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.sql;
|
package org.hibernate.query.sqm.sql;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized SemanticQueryWalker (SQM visitor) for producing SQL AST.
|
* Specialized SemanticQueryWalker (SQM visitor) for producing SQL AST.
|
||||||
@ -15,4 +17,5 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
||||||
|
Stack<Clause> getCurrentClauseStack();
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,16 @@
|
|||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
|
||||||
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.update.Assignment;
|
import org.hibernate.sql.ast.tree.update.Assignment;
|
||||||
@ -44,45 +45,63 @@ public static <T> BasicValuedPathInterpretation<T> from(
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
return new BasicValuedPathInterpretation<>( sqmPath, mapping, tableGroup );
|
final ColumnReference columnReference = (ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||||
|
SqlExpressionResolver.createColumnReferenceKey(
|
||||||
|
mapping.getContainingTableExpression(),
|
||||||
|
mapping.getMappedColumnExpression()
|
||||||
|
),
|
||||||
|
sacs -> new ColumnReference(
|
||||||
|
mapping.getMappedColumnExpression(),
|
||||||
|
tableGroup.resolveTableReference( mapping.getContainingTableExpression() )
|
||||||
|
.getIdentificationVariable(),
|
||||||
|
mapping.getJdbcMapping(),
|
||||||
|
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return new BasicValuedPathInterpretation<>( columnReference, sqmPath, mapping, tableGroup );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ColumnReference columnReference;
|
||||||
|
|
||||||
private final SqmBasicValuedSimplePath<T> sqmPath;
|
private final SqmBasicValuedSimplePath<T> sqmPath;
|
||||||
private final BasicValuedModelPart mapping;
|
private final BasicValuedModelPart mapping;
|
||||||
private final TableGroup tableGroup;
|
private final TableGroup tableGroup;
|
||||||
|
|
||||||
private Expression expression;
|
|
||||||
|
|
||||||
private BasicValuedPathInterpretation(
|
private BasicValuedPathInterpretation(
|
||||||
|
ColumnReference columnReference,
|
||||||
SqmBasicValuedSimplePath<T> sqmPath,
|
SqmBasicValuedSimplePath<T> sqmPath,
|
||||||
BasicValuedModelPart mapping,
|
BasicValuedModelPart mapping,
|
||||||
TableGroup tableGroup) {
|
TableGroup tableGroup) {
|
||||||
|
assert columnReference != null;
|
||||||
|
this.columnReference = columnReference;
|
||||||
|
|
||||||
|
assert sqmPath != null;
|
||||||
this.sqmPath = sqmPath;
|
this.sqmPath = sqmPath;
|
||||||
|
|
||||||
|
assert mapping != null;
|
||||||
this.mapping = mapping;
|
this.mapping = mapping;
|
||||||
|
|
||||||
|
assert tableGroup != null;
|
||||||
this.tableGroup = tableGroup;
|
this.tableGroup = tableGroup;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigablePath getNavigablePath() {
|
public SqmPath<T> getInterpretedSqmPath() {
|
||||||
return sqmPath.getNavigablePath();
|
return sqmPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPathSource<T> getSqmPathSource() {
|
public ModelPart getExpressionType() {
|
||||||
return sqmPath.getReferencedPathSource();
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// DomainResultProducer
|
// DomainResultProducer
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResultProducer<T> getDomainResultProducer(
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DomainResult<T> createDomainResult(
|
public DomainResult<T> createDomainResult(
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
@ -95,17 +114,6 @@ public void applySqlSelections(DomainResultCreationState creationState) {
|
|||||||
mapping.applySqlSelections( getNavigablePath(), tableGroup, creationState );
|
mapping.applySqlSelections( getNavigablePath(), tableGroup, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
// SqmExpressionInterpretation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression toSqlExpression(
|
|
||||||
Clause clause, SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applySqlAssignments(
|
public void applySqlAssignments(
|
||||||
Expression newValueExpression,
|
Expression newValueExpression,
|
||||||
@ -115,6 +123,11 @@ public void applySqlAssignments(
|
|||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
throw new NotYetImplementedFor6Exception( getClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||||
|
columnReference.accept( sqlTreeWalker );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BasicValuedPathInterpretation(" + sqmPath.getNavigablePath().getFullPath() + ')';
|
return "BasicValuedPathInterpretation(" + sqmPath.getNavigablePath().getFullPath() + ')';
|
||||||
|
@ -10,15 +10,15 @@
|
|||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
|
||||||
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.update.Assignment;
|
import org.hibernate.sql.ast.tree.update.Assignment;
|
||||||
@ -28,59 +28,67 @@
|
|||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class EmbeddableValuedPathInterpretation<T> implements AssignableSqmPathInterpretation<T>, DomainResultProducer<T> {
|
public class EmbeddableValuedPathInterpretation<T> implements AssignableSqmPathInterpretation<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static factory
|
* Static factory
|
||||||
*/
|
*/
|
||||||
public static <T> EmbeddableValuedPathInterpretation<T> from(
|
public static <T> EmbeddableValuedPathInterpretation<T> from(
|
||||||
SqmEmbeddedValuedSimplePath<T> sqmPath,
|
SqmEmbeddedValuedSimplePath<T> sqmPath,
|
||||||
SqlAstCreationState sqlAstCreationState,
|
SqmToSqlAstConverter converter,
|
||||||
SemanticQueryWalker sqmWalker) {
|
SemanticQueryWalker sqmWalker) {
|
||||||
final TableGroup tableGroup = SqmMappingModelHelper.resolveLhs( sqmPath.getNavigablePath(), sqlAstCreationState );
|
final TableGroup tableGroup = SqmMappingModelHelper.resolveLhs( sqmPath.getNavigablePath(), converter );
|
||||||
tableGroup.getModelPart().prepareAsLhs( sqmPath.getNavigablePath(), sqlAstCreationState );
|
tableGroup.getModelPart().prepareAsLhs( sqmPath.getNavigablePath(), converter );
|
||||||
|
|
||||||
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) tableGroup.getModelPart().findSubPart(
|
final EmbeddableValuedModelPart mapping = (EmbeddableValuedModelPart) tableGroup.getModelPart().findSubPart(
|
||||||
sqmPath.getReferencedPathSource().getPathName(),
|
sqmPath.getReferencedPathSource().getPathName(),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
return new EmbeddableValuedPathInterpretation<>( sqmPath, mapping, tableGroup );
|
return new EmbeddableValuedPathInterpretation<>(
|
||||||
|
mapping.toSqlExpression(
|
||||||
|
tableGroup,
|
||||||
|
converter.getCurrentClauseStack().getCurrent(),
|
||||||
|
converter,
|
||||||
|
converter
|
||||||
|
),
|
||||||
|
sqmPath,
|
||||||
|
mapping,
|
||||||
|
tableGroup
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final Expression sqlExpression;
|
||||||
|
|
||||||
private final SqmEmbeddedValuedSimplePath<T> sqmPath;
|
private final SqmEmbeddedValuedSimplePath<T> sqmPath;
|
||||||
private final EmbeddableValuedModelPart mapping;
|
private final EmbeddableValuedModelPart mapping;
|
||||||
private final TableGroup tableGroup;
|
private final TableGroup tableGroup;
|
||||||
|
|
||||||
public EmbeddableValuedPathInterpretation(
|
public EmbeddableValuedPathInterpretation(
|
||||||
|
Expression sqlExpression,
|
||||||
SqmEmbeddedValuedSimplePath<T> sqmPath,
|
SqmEmbeddedValuedSimplePath<T> sqmPath,
|
||||||
EmbeddableValuedModelPart mapping,
|
EmbeddableValuedModelPart mapping,
|
||||||
TableGroup tableGroup) {
|
TableGroup tableGroup) {
|
||||||
|
this.sqlExpression = sqlExpression;
|
||||||
this.sqmPath = sqmPath;
|
this.sqmPath = sqmPath;
|
||||||
this.mapping = mapping;
|
this.mapping = mapping;
|
||||||
this.tableGroup = tableGroup;
|
this.tableGroup = tableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigablePath getNavigablePath() {
|
public SqmPath<T> getInterpretedSqmPath() {
|
||||||
return sqmPath.getNavigablePath();
|
return sqmPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPathSource<T> getSqmPathSource() {
|
public ModelPart getExpressionType() {
|
||||||
return sqmPath.getReferencedPathSource();
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
// DomainResultProducer
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DomainResultProducer<T> getDomainResultProducer(
|
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||||
SqmToSqlAstConverter walker,
|
sqlExpression.accept( sqlTreeWalker );
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -93,18 +101,6 @@ public void applySqlSelections(DomainResultCreationState creationState) {
|
|||||||
mapping.applySqlSelections( getNavigablePath(), tableGroup, creationState );
|
mapping.applySqlSelections( getNavigablePath(), tableGroup, creationState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
// SqmPathInterpretation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression toSqlExpression(
|
|
||||||
Clause clause,
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return mapping.toSqlExpression( tableGroup, clause, walker, sqlAstCreationState );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applySqlAssignments(
|
public void applySqlAssignments(
|
||||||
Expression newValueExpression,
|
Expression newValueExpression,
|
||||||
|
@ -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.query.sqm.sql.internal;
|
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.sql.ast.Clause;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The interpretation of an SqmExpression as part of the SQM -> SQL conversion.
|
|
||||||
*
|
|
||||||
* Allows multi-column navigable references to be used anywhere a (SqlExpression)
|
|
||||||
* can be. The trick is to properly define methods on this interface for how the
|
|
||||||
* thing should be rendered into the SQL AST.
|
|
||||||
*
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public interface SqmExpressionInterpretation<T> extends SqmSelectableInterpretation<T> {
|
|
||||||
SqmExpressable<T> getExpressableType();
|
|
||||||
|
|
||||||
default Expression toSqlExpression(
|
|
||||||
Clause clause,
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,13 +9,8 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
import org.hibernate.metamodel.model.domain.internal.DomainModelHelper;
|
|
||||||
import org.hibernate.query.SemanticException;
|
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.exec.spi.JdbcParameter;
|
import org.hibernate.sql.exec.spi.JdbcParameter;
|
||||||
@ -23,44 +18,34 @@
|
|||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SqmParameterInterpretation implements SqmExpressionInterpretation {
|
public class SqmParameterInterpretation implements Expression {
|
||||||
private final SqmParameter sqmParameter;
|
private final SqmParameter sqmParameter;
|
||||||
private final List<JdbcParameter> jdbcParameters;
|
|
||||||
private final MappingModelExpressable valueMapping;
|
private final MappingModelExpressable valueMapping;
|
||||||
|
|
||||||
|
private final Expression resolvedExpression;
|
||||||
|
|
||||||
public SqmParameterInterpretation(
|
public SqmParameterInterpretation(
|
||||||
SqmParameter sqmParameter,
|
SqmParameter sqmParameter,
|
||||||
List<JdbcParameter> jdbcParameters,
|
List<JdbcParameter> jdbcParameters,
|
||||||
MappingModelExpressable valueMapping) {
|
MappingModelExpressable valueMapping) {
|
||||||
|
this.sqmParameter = sqmParameter;
|
||||||
this.valueMapping = valueMapping;
|
this.valueMapping = valueMapping;
|
||||||
|
|
||||||
assert jdbcParameters != null;
|
assert jdbcParameters != null;
|
||||||
assert jdbcParameters.size() > 0;
|
assert jdbcParameters.size() > 0;
|
||||||
|
|
||||||
this.sqmParameter = sqmParameter;
|
this.resolvedExpression = jdbcParameters.size() == 1
|
||||||
this.jdbcParameters = jdbcParameters;
|
? jdbcParameters.get( 0 )
|
||||||
|
: new SqlTuple( jdbcParameters, valueMapping );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressable getExpressableType() {
|
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||||
return sqmParameter.getExpressableType();
|
resolvedExpression.accept( sqlTreeWalker );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression toSqlExpression(
|
public MappingModelExpressable getExpressionType() {
|
||||||
Clause clause,
|
return valueMapping;
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
if ( jdbcParameters.size() == 1 ) {
|
|
||||||
return jdbcParameters.get( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SqlTuple( jdbcParameters, valueMapping );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResultProducer getDomainResultProducer(
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new SemanticException( "SqmParameter parameter cannot be a DomainResult" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,68 +6,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.sql.internal;
|
package org.hibernate.query.sqm.sql.internal;
|
||||||
|
|
||||||
import java.util.List;
|
import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
|
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.query.sqm.sql.ConversionException;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo (6.0) : consider having `SqmPathInterpretation` extend `org.hibernate.sql.ast.tree.expression.Expression`.
|
* Interpretation of a {@link SqmPath} as part of the translation to SQL AST
|
||||||
* - Basic paths would logically resolve to a `ColumnReference`
|
*
|
||||||
* - Composite and entity-valued paths would logically resolve to a `SqlTuple`
|
* @see org.hibernate.query.sqm.sql.SqmToSqlAstConverter
|
||||||
|
* @see #getInterpretedSqmPath
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqmPathInterpretation<T> extends SqmExpressionInterpretation<T> {
|
public interface SqmPathInterpretation<T> extends Expression, DomainResultProducer<T> {
|
||||||
NavigablePath getNavigablePath();
|
default NavigablePath getNavigablePath() {
|
||||||
|
return getInterpretedSqmPath().getNavigablePath();
|
||||||
@Override
|
|
||||||
default SqmPathSource<T> getExpressableType() {
|
|
||||||
return getSqmPathSource();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SqmPathSource<T> getSqmPathSource();
|
SqmPath<T> getInterpretedSqmPath();
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// default Expression toSqlExpression(SqlAstCreationState sqlAstCreationState) {
|
ModelPart getExpressionType();
|
||||||
// throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
// final TableGroup tableGroup;
|
|
||||||
//
|
|
||||||
// if ( getSqmPathSource() instanceof BasicSqmPathSource ) {
|
|
||||||
// // maybe we should register the LHS TableGroup for the basic value
|
|
||||||
// // under its NavigablePath, similar to what we do for embeddables
|
|
||||||
// tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( getNavigablePath().getParent() );
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // for embeddable-, entity- and plural-valued Navigables we maybe do not have a TableGroup
|
|
||||||
// final TableGroup thisTableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( getNavigablePath() );
|
|
||||||
// if ( thisTableGroup != null ) {
|
|
||||||
// tableGroup = thisTableGroup;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// final NavigablePath lhsNavigablePath = getNavigablePath().getParent();
|
|
||||||
// if ( lhsNavigablePath == null ) {
|
|
||||||
// throw new ConversionException( "Could not find TableGroup to use - " + getNavigablePath().getFullPath() );
|
|
||||||
// }
|
|
||||||
// tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( lhsNavigablePath );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sqlAstCreationState.getCreationContext().getDomainModel().resolveMappingExpressable( )
|
|
||||||
//
|
|
||||||
// final List list = getNavigable().resolveColumnReferences( tableGroup, sqlAstCreationState );
|
|
||||||
// if ( list.size() == 1 ) {
|
|
||||||
// assert list.get( 0 ) instanceof Expression;
|
|
||||||
// return (Expression) list.get( 0 );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return new SqlTuple( list, sqlAstCreationState.getJdbcMapping() );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
@ -32,10 +31,6 @@
|
|||||||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||||
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
|
||||||
import org.hibernate.sql.results.internal.domain.instantiation.DynamicInstantiation;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
|
||||||
@ -53,6 +48,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
|
import org.hibernate.sql.results.internal.domain.instantiation.DynamicInstantiation;
|
||||||
import org.hibernate.sql.results.spi.CircularFetchDetector;
|
import org.hibernate.sql.results.spi.CircularFetchDetector;
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
@ -141,8 +137,7 @@ public Void visitSelection(SqmSelection sqmSelection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DomainResultProducer resolveDomainResultProducer(SqmSelection sqmSelection) {
|
private DomainResultProducer resolveDomainResultProducer(SqmSelection sqmSelection) {
|
||||||
SqmSelectableInterpretation<?> interpretation = (SqmSelectableInterpretation<?>) sqmSelection.getSelectableNode().accept( this );
|
return (DomainResultProducer) sqmSelection.getSelectableNode().accept( this );
|
||||||
return interpretation.getDomainResultProducer( this, getSqlAstCreationState() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int fetchDepth = 0;
|
private int fetchDepth = 0;
|
||||||
|
@ -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.query.sqm.sql.internal;
|
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
public interface SqmSelectableInterpretation<T> {
|
|
||||||
default DomainResultProducer<T> getDomainResultProducer(SqmToSqlAstConverter walker, SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +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.query.sqm.sql.internal;
|
|
||||||
|
|
||||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
|
||||||
import org.hibernate.query.sqm.sql.ConversionException;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Steve Ebersole
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public class SqmSqlHelper {
|
|
||||||
private SqmSqlHelper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TableGroup resolveTableGroup(SqmPath<?> sqmPath, SqlAstCreationState creationState) {
|
|
||||||
SqmPath<?> lhs = sqmPath;
|
|
||||||
while ( lhs.getReferencedPathSource().getSqmPathType() instanceof EmbeddableDomainType ) {
|
|
||||||
lhs = lhs.getLhs();
|
|
||||||
}
|
|
||||||
|
|
||||||
final TableGroup tableGroup = creationState.getFromClauseAccess().findTableGroup( lhs.getNavigablePath() );
|
|
||||||
if ( tableGroup != null ) {
|
|
||||||
return tableGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ConversionException( "Could not locate TableGroup to use : " + lhs.getNavigablePath() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.query.sqm.sql.internal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class SqmTupleInterpretation<T> extends SqlTuple {
|
||||||
|
|
||||||
|
public static <T> SqmTupleInterpretation<T> from(
|
||||||
|
SqmTuple<T> sqmTuple,
|
||||||
|
SemanticQueryWalker<?> walker,
|
||||||
|
SqlAstCreationState sqlAstCreationState) {
|
||||||
|
final List<Expression> groupedSqlExpressions = new ArrayList<>();
|
||||||
|
|
||||||
|
for ( SqmExpression<?> groupedExpression : sqmTuple.getGroupedExpressions() ) {
|
||||||
|
groupedSqlExpressions.add( (Expression) groupedExpression.accept( walker ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SqmTupleInterpretation<>(
|
||||||
|
sqmTuple,
|
||||||
|
groupedSqlExpressions,
|
||||||
|
SqmMappingModelHelper.resolveMappingModelExpressable( sqmTuple, sqlAstCreationState )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final SqmTuple<T> interpretedSqmTuple;
|
||||||
|
|
||||||
|
public SqmTupleInterpretation(
|
||||||
|
SqmTuple<T> sqmTuple,
|
||||||
|
List<? extends Expression> expressions,
|
||||||
|
MappingModelExpressable valueMapping) {
|
||||||
|
|
||||||
|
super( expressions, valueMapping );
|
||||||
|
interpretedSqmTuple = sqmTuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SqmTuple<T> getInterpretedSqmTuple() {
|
||||||
|
return interpretedSqmTuple;
|
||||||
|
}
|
||||||
|
}
|
@ -31,11 +31,6 @@ public AbstractSqmExpression(SqmExpressable<T> type, NodeBuilder criteriaBuilder
|
|||||||
super( type, criteriaBuilder );
|
super( type, criteriaBuilder );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmExpressable<T> getExpressableType() {
|
|
||||||
return getNodeType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void applyInferableType(SqmExpressable<?> type) {
|
public final void applyInferableType(SqmExpressable<?> type) {
|
||||||
if ( type == null ) {
|
if ( type == null ) {
|
||||||
|
@ -65,11 +65,6 @@ public EnumJavaTypeDescriptor<Enum> getExpressableJavaTypeDescriptor() {
|
|||||||
return referencedEnumTypeDescriptor;
|
return referencedEnumTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmExpressable<Enum> getExpressableType() {
|
|
||||||
return expressable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// SemanticPathPart
|
// SemanticPathPart
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
import org.hibernate.metamodel.model.domain.DomainType;
|
import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.query.criteria.JpaExpression;
|
import org.hibernate.query.criteria.JpaExpression;
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
import org.hibernate.query.sqm.SqmExpressable;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmExpressionInterpretation;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
|
|
||||||
@ -29,7 +28,7 @@
|
|||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqmExpression<T> extends SqmSelectableNode<T>, JpaExpression<T>, SqmExpressionInterpretation<T> {
|
public interface SqmExpression<T> extends SqmSelectableNode<T>, JpaExpression<T> {
|
||||||
/**
|
/**
|
||||||
* The expression's type.
|
* The expression's type.
|
||||||
*
|
*
|
||||||
|
@ -77,11 +77,6 @@ public T getValue() {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmExpressable<T> getExpressableType() {
|
|
||||||
return expressable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JavaTypeDescriptor<T> getFieldJavaTypeDescriptor() {
|
public JavaTypeDescriptor<T> getFieldJavaTypeDescriptor() {
|
||||||
return fieldJavaTypeDescriptor;
|
return fieldJavaTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,7 @@
|
|||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
import org.hibernate.query.sqm.SqmExpressable;
|
||||||
import org.hibernate.query.sqm.internal.SqmMappingModelHelper;
|
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||||
import org.hibernate.sql.ast.Clause;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a literal value in the sqm, e.g.<ul>
|
* Represents a literal value in the sqm, e.g.<ul>
|
||||||
@ -46,18 +40,6 @@ public <R> R accept(SemanticQueryWalker<R> walker) {
|
|||||||
return walker.visitLiteral( this );
|
return walker.visitLiteral( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression toSqlExpression(
|
|
||||||
Clause clause,
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return new QueryLiteral(
|
|
||||||
getLiteralValue(),
|
|
||||||
SqmMappingModelHelper.resolveMappingModelExpressable( this, sqlAstCreationState ),
|
|
||||||
clause
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asLoggableText() {
|
public String asLoggableText() {
|
||||||
return "Literal( " + value + ")";
|
return "Literal( " + value + ")";
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.tree.expression;
|
package org.hibernate.query.sqm.tree.expression;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -16,14 +15,7 @@
|
|||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
import org.hibernate.query.sqm.SqmExpressable;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmExpressionInterpretation;
|
|
||||||
import org.hibernate.query.sqm.tree.select.SqmJpaCompoundSelection;
|
import org.hibernate.query.sqm.tree.select.SqmJpaCompoundSelection;
|
||||||
import org.hibernate.sql.ast.Clause;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
public class SqmTuple<T>
|
public class SqmTuple<T>
|
||||||
extends AbstractSqmExpression<T>
|
extends AbstractSqmExpression<T>
|
||||||
implements JpaCompoundSelection<T>, SqmExpressionInterpretation<T> {
|
implements JpaCompoundSelection<T> {
|
||||||
private final List<SqmExpression<?>> groupedExpressions;
|
private final List<SqmExpression<?>> groupedExpressions;
|
||||||
|
|
||||||
public SqmTuple(NodeBuilder nodeBuilder, SqmExpression<?>... groupedExpressions) {
|
public SqmTuple(NodeBuilder nodeBuilder, SqmExpression<?>... groupedExpressions) {
|
||||||
@ -63,6 +55,10 @@ public SqmTuple(List<SqmExpression<?>> groupedExpressions, SqmExpressable<T> typ
|
|||||||
applyInferableType( type );
|
applyInferableType( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<SqmExpression<?>> getGroupedExpressions() {
|
||||||
|
return groupedExpressions;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressable<T> getNodeType() {
|
public SqmExpressable<T> getNodeType() {
|
||||||
final SqmExpressable<T> expressableType = super.getNodeType();
|
final SqmExpressable<T> expressableType = super.getNodeType();
|
||||||
@ -86,37 +82,6 @@ public <X> X accept(SemanticQueryWalker<X> walker) {
|
|||||||
return walker.visitTuple( this );
|
return walker.visitTuple( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression toSqlExpression(
|
|
||||||
Clause clause,
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
final List<Expression> groupedSqlExpressions = new ArrayList<>();
|
|
||||||
|
|
||||||
for ( SqmExpression groupedExpression : groupedExpressions ) {
|
|
||||||
final SqmExpressionInterpretation interpretation = (SqmExpressionInterpretation) groupedExpression.accept( walker );
|
|
||||||
final Expression sqlExpression = interpretation.toSqlExpression(
|
|
||||||
clause, walker,
|
|
||||||
sqlAstCreationState
|
|
||||||
);
|
|
||||||
|
|
||||||
groupedSqlExpressions.add( sqlExpression );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SqlTuple(
|
|
||||||
groupedSqlExpressions,
|
|
||||||
sqlAstCreationState.getCreationContext().getDomainModel()
|
|
||||||
.resolveMappingExpressable( getExpressableType() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResultProducer getDomainResultProducer(
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String asLoggableText() {
|
public String asLoggableText() {
|
||||||
return toString();
|
return toString();
|
||||||
@ -134,7 +99,7 @@ public boolean isCompoundSelection() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends JpaSelection<?>> getSelectionItems() {
|
public List<? extends JpaSelection<?>> getSelectionItems() {
|
||||||
return groupedExpressions;
|
return getGroupedExpressions();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
@ -16,15 +15,12 @@
|
|||||||
import org.hibernate.query.criteria.JpaRoot;
|
import org.hibernate.query.criteria.JpaRoot;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||||
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
|
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
|
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
@ -102,20 +98,6 @@ public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarge
|
|||||||
return new SqmTreatedRoot<>( this, treatTarget, nodeBuilder() );
|
return new SqmTreatedRoot<>( this, treatTarget, nodeBuilder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResultProducer<E> getDomainResultProducer(
|
|
||||||
SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Expression toSqlExpression(
|
|
||||||
Clause clause, SqmToSqlAstConverter walker,
|
|
||||||
SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitJdbcTypes(Consumer<JdbcMapping> action, TypeConfiguration typeConfiguration) {
|
public void visitJdbcTypes(Consumer<JdbcMapping> action, TypeConfiguration typeConfiguration) {
|
||||||
final String entityName = getReferencedPathSource().getHibernateEntityName();
|
final String entityName = getReferencedPathSource().getHibernateEntityName();
|
||||||
|
@ -9,12 +9,7 @@
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import javax.persistence.criteria.Selection;
|
import javax.persistence.criteria.Selection;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.query.criteria.JpaSelection;
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmSelectableInterpretation;
|
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
|
|
||||||
@ -24,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqmSelectableNode<T> extends JpaSelection<T>, SqmTypedNode<T>, SqmVisitableNode, SqmSelectableInterpretation<T> {
|
public interface SqmSelectableNode<T> extends JpaSelection<T>, SqmTypedNode<T>, SqmVisitableNode {
|
||||||
/**
|
/**
|
||||||
* Visit each of this selectable's direct sub-selectables - used to
|
* Visit each of this selectable's direct sub-selectables - used to
|
||||||
* support JPA's {@link Selection} model (which is really a "selectable",
|
* support JPA's {@link Selection} model (which is really a "selectable",
|
||||||
@ -34,8 +29,4 @@ public interface SqmSelectableNode<T> extends JpaSelection<T>, SqmTypedNode<T>,
|
|||||||
* @see Selection#getCompoundSelectionItems()
|
* @see Selection#getCompoundSelectionItems()
|
||||||
*/
|
*/
|
||||||
void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer);
|
void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer);
|
||||||
|
|
||||||
default DomainResultProducer<T> getDomainResultProducer(SqmToSqlAstConverter walker, SqlAstCreationState sqlAstCreationState) {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
import org.hibernate.query.criteria.JpaSelection;
|
import org.hibernate.query.criteria.JpaSelection;
|
||||||
import org.hibernate.query.criteria.JpaSubQuery;
|
import org.hibernate.query.criteria.JpaSubQuery;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmExpressable;
|
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.SqmExpressable;
|
||||||
import org.hibernate.query.sqm.tree.SqmQuery;
|
import org.hibernate.query.sqm.tree.SqmQuery;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmBagJoin;
|
import org.hibernate.query.sqm.tree.domain.SqmBagJoin;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmListJoin;
|
import org.hibernate.query.sqm.tree.domain.SqmListJoin;
|
||||||
@ -72,11 +72,6 @@ public SqmSubQuery(
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqmExpressable<T> getExpressableType() {
|
|
||||||
return expressableType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmQuery<?> getContainingQuery() {
|
public SqmQuery<?> getContainingQuery() {
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -22,5 +22,7 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface JdbcLiteralFormatter<T> {
|
public interface JdbcLiteralFormatter<T> {
|
||||||
|
String NULL = "null";
|
||||||
|
|
||||||
String toJdbcLiteral(T value, Dialect dialect, SharedSessionContractImplementor session);
|
String toJdbcLiteral(T value, Dialect dialect, SharedSessionContractImplementor session);
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,24 @@
|
|||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.query.sqm.sql.SqlExpressionResolver;
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||||
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
||||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||||
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
|
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We classify literals different based on their source so that we can handle then differently
|
* We classify literals different based on their source so that we can handle then differently
|
||||||
@ -31,10 +38,10 @@
|
|||||||
public abstract class AbstractLiteral<T>
|
public abstract class AbstractLiteral<T>
|
||||||
implements JdbcParameterBinder, Expression, DomainResultProducer<T> {
|
implements JdbcParameterBinder, Expression, DomainResultProducer<T> {
|
||||||
private final Object value;
|
private final Object value;
|
||||||
private final MappingModelExpressable type;
|
private final BasicValuedMapping type;
|
||||||
private final Clause clause;
|
private final Clause clause;
|
||||||
|
|
||||||
public AbstractLiteral(Object value, MappingModelExpressable type, Clause clause) {
|
public AbstractLiteral(Object value, BasicValuedMapping type, Clause clause) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.clause = clause;
|
this.clause = clause;
|
||||||
@ -49,15 +56,51 @@ public boolean isInSelect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingModelExpressable getExpressionType() {
|
public BasicValuedMapping getExpressionType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DomainResult createDomainResult(
|
public DomainResult<T> createDomainResult(
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlAstCreationState().getSqlExpressionResolver();
|
||||||
|
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||||
|
this,
|
||||||
|
type.getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
|
||||||
|
creationState.getSqlAstCreationState()
|
||||||
|
.getCreationContext()
|
||||||
|
.getSessionFactory()
|
||||||
|
.getTypeConfiguration()
|
||||||
|
);
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return new BasicResult<>(
|
||||||
|
sqlSelection.getJdbcResultSetIndex(),
|
||||||
|
resultVariable,
|
||||||
|
type.getMappedTypeDescriptor().getMappedJavaTypeDescriptor()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlSelection createSqlSelection(
|
||||||
|
int jdbcPosition,
|
||||||
|
int valuesArrayPosition,
|
||||||
|
JavaTypeDescriptor javaTypeDescriptor,
|
||||||
|
TypeConfiguration typeConfiguration) {
|
||||||
|
return new SqlSelectionImpl(
|
||||||
|
jdbcPosition,
|
||||||
|
valuesArrayPosition,
|
||||||
|
this,
|
||||||
|
type.getJdbcMapping()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJdbcTypes(
|
||||||
|
Consumer<JdbcMapping> action,
|
||||||
|
TypeConfiguration typeConfiguration) {
|
||||||
|
action.accept( type.getJdbcMapping() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.expression;
|
package org.hibernate.sql.ast.tree.expression;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class QueryLiteral<T> extends AbstractLiteral<T> {
|
public class QueryLiteral<T> extends AbstractLiteral<T> {
|
||||||
public QueryLiteral(Object value, MappingModelExpressable expressableType, Clause clause) {
|
public QueryLiteral(Object value, BasicValuedMapping expressableType, Clause clause) {
|
||||||
super( value, expressableType, clause );
|
super( value, expressableType, clause );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.SqlAstCreationState;
|
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
|
|
||||||
@ -77,10 +74,4 @@ public TableReference getPrimaryTableReference() {
|
|||||||
public List<TableReferenceJoin> getTableReferenceJoins() {
|
public List<TableReferenceJoin> getTableReferenceJoins() {
|
||||||
return tableJoins;
|
return tableJoins;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResultProducer getDomainResultProducer(
|
|
||||||
SqmToSqlAstConverter walker, SqlAstCreationState sqlAstCreationState) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,9 @@
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.metamodel.mapping.ModelPart;
|
|
||||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||||
import org.hibernate.query.NavigablePath;
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmSelectableInterpretation;
|
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
import org.hibernate.sql.ast.spi.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
@ -30,7 +28,7 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface TableGroup
|
public interface TableGroup
|
||||||
extends SqlAstNode, ColumnReferenceQualifier, DomainResultProducer, SqmSelectableInterpretation {
|
extends SqlAstNode, ColumnReferenceQualifier, DomainResultProducer {
|
||||||
NavigablePath getNavigablePath();
|
NavigablePath getNavigablePath();
|
||||||
|
|
||||||
ModelPartContainer getModelPart();
|
ModelPartContainer getModelPart();
|
||||||
|
@ -37,6 +37,10 @@ public JavaTypeDescriptor getResultJavaTypeDescriptor() {
|
|||||||
public ArgumentReader<A> createResultAssembler(
|
public ArgumentReader<A> createResultAssembler(
|
||||||
Consumer<Initializer> initializerCollector,
|
Consumer<Initializer> initializerCollector,
|
||||||
AssemblerCreationState creationState) {
|
AssemblerCreationState creationState) {
|
||||||
return null;
|
//noinspection unchecked
|
||||||
|
return new ArgumentReader(
|
||||||
|
realDomainResult.createResultAssembler( initializerCollector, creationState ),
|
||||||
|
getResultVariable()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,20 +6,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.sql.results.internal.domain.instantiation;
|
package org.hibernate.sql.results.internal.domain.instantiation;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.internal.util.StringHelper;
|
|
||||||
import org.hibernate.query.DynamicInstantiationNature;
|
import org.hibernate.query.DynamicInstantiationNature;
|
||||||
import org.hibernate.query.sqm.sql.ConversionException;
|
import org.hibernate.query.sqm.sql.ConversionException;
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||||
import org.hibernate.query.sqm.tree.expression.Compatibility;
|
|
||||||
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
|
||||||
import org.hibernate.sql.results.spi.DomainResult;
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
|
||||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
@ -116,131 +111,124 @@ public String toString() {
|
|||||||
public DomainResult createDomainResult(
|
public DomainResult createDomainResult(
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
DomainResultCreationState creationState) {
|
DomainResultCreationState creationState) {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
//noinspection unchecked
|
||||||
|
return new DynamicInstantiationResultImpl(
|
||||||
|
resultVariable,
|
||||||
|
getNature(),
|
||||||
|
getTargetJavaTypeDescriptor(),
|
||||||
|
getArguments().stream()
|
||||||
|
.map( argument -> argument.buildArgumentDomainResult( creationState ) )
|
||||||
|
.collect( Collectors.toList() )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
// @Override
|
|
||||||
// @SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
// public DomainResult createDomainResult(
|
// private static DomainResultAssembler resolveAssembler(
|
||||||
// String resultVariable,
|
// DynamicInstantiation dynamicInstantiation,
|
||||||
// DomainResultCreationState creationState) {
|
// boolean areAllArgumentsAliased,
|
||||||
// return new DynamicInstantiationResult(
|
// boolean areAnyArgumentsAliased,
|
||||||
// resultVariable,
|
// List<String> duplicatedAliases,
|
||||||
// getNature(),
|
// List<ArgumentReader<?>> argumentReaders,
|
||||||
// (JavaTypeDescriptor) getTargetJavaTypeDescriptor(),
|
// AssemblerCreationState creationState) {
|
||||||
// getArguments().stream()
|
//
|
||||||
// .map( argument -> argument.buildArgumentDomainResult( creationState ) )
|
// if ( dynamicInstantiation.getNature() == DynamicInstantiationNature.LIST ) {
|
||||||
// .collect( Collectors.toList() )
|
// if ( log.isDebugEnabled() && areAnyArgumentsAliased ) {
|
||||||
// );
|
// log.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
|
||||||
|
// }
|
||||||
|
// return new DynamicInstantiationListAssemblerImpl(
|
||||||
|
// (JavaTypeDescriptor<List>) dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
||||||
|
// argumentReaders
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else if ( dynamicInstantiation.getNature() == DynamicInstantiationNature.MAP ) {
|
||||||
|
// if ( ! areAllArgumentsAliased ) {
|
||||||
|
// throw new IllegalStateException( "Map dynamic instantiation contained one or more arguments with no alias" );
|
||||||
|
// }
|
||||||
|
// if ( !duplicatedAliases.isEmpty() ) {
|
||||||
|
// throw new IllegalStateException(
|
||||||
|
// "Map dynamic instantiation contained arguments with duplicated aliases [" + StringHelper.join( ",", duplicatedAliases ) + "]"
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return new DynamicInstantiationMapAssemblerImpl(
|
||||||
|
// (JavaTypeDescriptor<Map>) dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
||||||
|
// argumentReaders
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// // find a constructor matching argument types
|
||||||
|
// constructor_loop:
|
||||||
|
// for ( Constructor constructor : dynamicInstantiation.getTargetJavaTypeDescriptor().getJavaType().getDeclaredConstructors() ) {
|
||||||
|
// if ( constructor.getParameterTypes().length != dynamicInstantiation.arguments.size() ) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for ( int i = 0; i < dynamicInstantiation.arguments.size(); i++ ) {
|
||||||
|
// final ArgumentReader argumentReader = argumentReaders.get( i );
|
||||||
|
// final JavaTypeDescriptor argumentTypeDescriptor = creationState.getSqlAstCreationContext().getDomainModel()
|
||||||
|
// .getTypeConfiguration()
|
||||||
|
// .getJavaTypeDescriptorRegistry()
|
||||||
|
// .resolveDescriptor( constructor.getParameterTypes()[i] );
|
||||||
|
//
|
||||||
|
// final boolean assignmentCompatible = Compatibility.areAssignmentCompatible(
|
||||||
|
// argumentTypeDescriptor,
|
||||||
|
// argumentReader.getAssembledJavaTypeDescriptor()
|
||||||
|
// );
|
||||||
|
// if ( !assignmentCompatible ) {
|
||||||
|
// log.debugf(
|
||||||
|
// "Skipping constructor for dynamic-instantiation match due to argument mismatch [%s] : %s -> %s",
|
||||||
|
// i,
|
||||||
|
// constructor.getParameterTypes()[i].getName(),
|
||||||
|
// argumentTypeDescriptor.getJavaType().getName()
|
||||||
|
// );
|
||||||
|
// continue constructor_loop;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constructor.setAccessible( true );
|
||||||
|
// return new DynamicInstantiationConstructorAssemblerImpl(
|
||||||
|
// constructor,
|
||||||
|
// dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
||||||
|
// argumentReaders
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// log.debugf(
|
||||||
|
// "Could not locate appropriate constructor for dynamic instantiation of [%s]; attempting bean-injection instantiation",
|
||||||
|
// dynamicInstantiation.getTargetJavaTypeDescriptor().getJavaType().getName()
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if ( ! areAllArgumentsAliased ) {
|
||||||
|
// throw new IllegalStateException(
|
||||||
|
// "Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection"
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if ( !duplicatedAliases.isEmpty() ) {
|
||||||
|
// throw new IllegalStateException(
|
||||||
|
// "Could not determine appropriate instantiation strategy - no matching constructor found and arguments defined duplicated aliases [" +
|
||||||
|
// StringHelper.join( ",", duplicatedAliases ) + "] for bean-injection"
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return new DynamicInstantiationInjectionAssemblerImpl(
|
||||||
|
// dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
||||||
|
// argumentReaders
|
||||||
|
// );
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@SuppressWarnings("unchecked")
|
// class Builder {
|
||||||
private static DomainResultAssembler resolveAssembler(
|
// private final DynamicInstantiationNature nature;
|
||||||
DynamicInstantiation dynamicInstantiation,
|
// private final JavaTypeDescriptor<T> targetJavaTypeDescriptor;
|
||||||
boolean areAllArgumentsAliased,
|
// private List<DynamicInstantiationArgument> arguments;
|
||||||
boolean areAnyArgumentsAliased,
|
//
|
||||||
List<String> duplicatedAliases,
|
// public Builder(
|
||||||
List<ArgumentReader<?>> argumentReaders,
|
// DynamicInstantiationNature nature,
|
||||||
AssemblerCreationState creationState) {
|
// JavaTypeDescriptor<T> targetJavaTypeDescriptor) {
|
||||||
|
// this.nature = nature;
|
||||||
if ( dynamicInstantiation.getNature() == DynamicInstantiationNature.LIST ) {
|
// this.targetJavaTypeDescriptor = targetJavaTypeDescriptor;
|
||||||
if ( log.isDebugEnabled() && areAnyArgumentsAliased ) {
|
// }
|
||||||
log.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
|
//
|
||||||
}
|
//
|
||||||
return new DynamicInstantiationListAssemblerImpl(
|
// }
|
||||||
(JavaTypeDescriptor<List>) dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( dynamicInstantiation.getNature() == DynamicInstantiationNature.MAP ) {
|
|
||||||
if ( ! areAllArgumentsAliased ) {
|
|
||||||
throw new IllegalStateException( "Map dynamic instantiation contained one or more arguments with no alias" );
|
|
||||||
}
|
|
||||||
if ( !duplicatedAliases.isEmpty() ) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Map dynamic instantiation contained arguments with duplicated aliases [" + StringHelper.join( ",", duplicatedAliases ) + "]"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return new DynamicInstantiationMapAssemblerImpl(
|
|
||||||
(JavaTypeDescriptor<Map>) dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// find a constructor matching argument types
|
|
||||||
constructor_loop:
|
|
||||||
for ( Constructor constructor : dynamicInstantiation.getTargetJavaTypeDescriptor().getJavaType().getDeclaredConstructors() ) {
|
|
||||||
if ( constructor.getParameterTypes().length != dynamicInstantiation.arguments.size() ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < dynamicInstantiation.arguments.size(); i++ ) {
|
|
||||||
final ArgumentReader argumentReader = argumentReaders.get( i );
|
|
||||||
final JavaTypeDescriptor argumentTypeDescriptor = creationState.getSqlAstCreationContext().getDomainModel()
|
|
||||||
.getTypeConfiguration()
|
|
||||||
.getJavaTypeDescriptorRegistry()
|
|
||||||
.resolveDescriptor( constructor.getParameterTypes()[i] );
|
|
||||||
|
|
||||||
final boolean assignmentCompatible = Compatibility.areAssignmentCompatible(
|
|
||||||
argumentTypeDescriptor,
|
|
||||||
argumentReader.getAssembledJavaTypeDescriptor()
|
|
||||||
);
|
|
||||||
if ( !assignmentCompatible ) {
|
|
||||||
log.debugf(
|
|
||||||
"Skipping constructor for dynamic-instantiation match due to argument mismatch [%s] : %s -> %s",
|
|
||||||
i,
|
|
||||||
constructor.getParameterTypes()[i].getName(),
|
|
||||||
argumentTypeDescriptor.getJavaType().getName()
|
|
||||||
);
|
|
||||||
continue constructor_loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor.setAccessible( true );
|
|
||||||
return new DynamicInstantiationConstructorAssemblerImpl(
|
|
||||||
constructor,
|
|
||||||
dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debugf(
|
|
||||||
"Could not locate appropriate constructor for dynamic instantiation of [%s]; attempting bean-injection instantiation",
|
|
||||||
dynamicInstantiation.getTargetJavaTypeDescriptor().getJavaType().getName()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
if ( ! areAllArgumentsAliased ) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ( !duplicatedAliases.isEmpty() ) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Could not determine appropriate instantiation strategy - no matching constructor found and arguments defined duplicated aliases [" +
|
|
||||||
StringHelper.join( ",", duplicatedAliases ) + "] for bean-injection"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DynamicInstantiationInjectionAssemblerImpl(
|
|
||||||
dynamicInstantiation.getTargetJavaTypeDescriptor(),
|
|
||||||
argumentReaders
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Builder {
|
|
||||||
private final DynamicInstantiationNature nature;
|
|
||||||
private final JavaTypeDescriptor<T> targetJavaTypeDescriptor;
|
|
||||||
private List<DynamicInstantiationArgument> arguments;
|
|
||||||
|
|
||||||
public Builder(
|
|
||||||
DynamicInstantiationNature nature,
|
|
||||||
JavaTypeDescriptor<T> targetJavaTypeDescriptor) {
|
|
||||||
this.nature = nature;
|
|
||||||
this.targetJavaTypeDescriptor = targetJavaTypeDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.spi.JdbcLiteralFormatter;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
import static org.hibernate.sql.ast.spi.JdbcLiteralFormatter.NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Types#NVARCHAR NVARCHAR} handling.
|
* Descriptor for {@link Types#NVARCHAR NVARCHAR} handling.
|
||||||
*
|
*
|
||||||
@ -38,6 +41,11 @@ public boolean canBeRemapped() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||||
|
return (value, dialect, session) -> value == null ? NULL : "'" + value.toString() + "'";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||||
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.spi.JdbcLiteralFormatter;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
import static org.hibernate.sql.ast.spi.JdbcLiteralFormatter.NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor for {@link Types#VARCHAR VARCHAR} handling.
|
* Descriptor for {@link Types#VARCHAR VARCHAR} handling.
|
||||||
*
|
*
|
||||||
@ -38,6 +41,11 @@ public boolean canBeRemapped() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> JdbcLiteralFormatter<T> getJdbcLiteralFormatter(JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||||
|
return (value, dialect, session) -> value == null ? NULL : "'" + value.toString() + "'";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||||
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
return new BasicBinder<X>( javaTypeDescriptor, this ) {
|
||||||
|
@ -163,6 +163,14 @@ public static class Component {
|
|||||||
private String attribute1;
|
private String attribute1;
|
||||||
private String attribute2;
|
private String attribute2;
|
||||||
|
|
||||||
|
public Component() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Component(String attribute1, String attribute2) {
|
||||||
|
this.attribute1 = attribute1;
|
||||||
|
this.attribute2 = attribute2;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAttribute1() {
|
public String getAttribute1() {
|
||||||
return attribute1;
|
return attribute1;
|
||||||
}
|
}
|
||||||
|
@ -125,15 +125,6 @@ public void testSimpleHqlInterpretation(SessionFactoryScope scope) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSimpleHqlExecution(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
final QueryImplementor<String> query = session.createQuery( "select e.name from SimpleEntity e", String.class );
|
|
||||||
query.list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@Test
|
@Test
|
||||||
public void testConvertedHqlInterpretation(SessionFactoryScope scope) {
|
public void testConvertedHqlInterpretation(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
@ -232,46 +223,6 @@ public void testConvertedHqlInterpretation(SessionFactoryScope scope) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertedHqlExecution(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
final QueryImplementor<Gender> query = session.createQuery( "select e.gender from SimpleEntity e", Gender.class );
|
|
||||||
query.list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSelectRootHqlExecution(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
final QueryImplementor<SimpleEntity> query = session.createQuery( "select e from SimpleEntity e", SimpleEntity.class );
|
|
||||||
query.list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSelectEmbeddedHqlExecution(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
final QueryImplementor<Component> query = session.createQuery( "select e.component from SimpleEntity e", Component.class );
|
|
||||||
query.list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSelectEmbeddableSubPathHqlExecution(SessionFactoryScope scope) {
|
|
||||||
scope.inTransaction(
|
|
||||||
session -> {
|
|
||||||
final QueryImplementor<String> query = session.createQuery( "select e.component.attribute1 from SimpleEntity e", String.class );
|
|
||||||
query.list();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadQueryResultType(SessionFactoryScope scope) {
|
public void testBadQueryResultType(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Component;
|
||||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
|
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
|
||||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender;
|
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender;
|
||||||
|
import org.hibernate.query.Query;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
@ -24,6 +26,7 @@
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.FEMALE;
|
import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.FEMALE;
|
||||||
import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.MALE;
|
import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.MALE;
|
||||||
@ -33,13 +36,21 @@
|
|||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
@DomainModel(
|
@DomainModel(
|
||||||
annotatedClasses = SimpleEntity.class
|
annotatedClasses = SimpleEntity.class,
|
||||||
|
extraQueryImportClasses = {
|
||||||
|
SmokeTests.ListItemDto.class,
|
||||||
|
SmokeTests.CategorizedListItemDto.class,
|
||||||
|
SmokeTests.CompoundDto.class,
|
||||||
|
SmokeTests.BasicSetterBasedDto.class
|
||||||
|
}
|
||||||
)
|
)
|
||||||
@ServiceRegistry(
|
@ServiceRegistry(
|
||||||
settings = @ServiceRegistry.Setting(
|
settings = {
|
||||||
name = AvailableSettings.HBM2DDL_AUTO,
|
@ServiceRegistry.Setting(
|
||||||
value = "create-drop"
|
name = AvailableSettings.HBM2DDL_AUTO,
|
||||||
)
|
value = "create-drop"
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
public class SmokeTests {
|
public class SmokeTests {
|
||||||
@ -53,6 +64,7 @@ public void setUp(SessionFactoryScope scope) {
|
|||||||
simpleEntity.setGender( FEMALE );
|
simpleEntity.setGender( FEMALE );
|
||||||
simpleEntity.setName( "Fab" );
|
simpleEntity.setName( "Fab" );
|
||||||
simpleEntity.setGender2( MALE );
|
simpleEntity.setGender2( MALE );
|
||||||
|
simpleEntity.setComponent( new Component( "a1", "a2" ) );
|
||||||
session.save( simpleEntity );
|
session.save( simpleEntity );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -73,7 +85,7 @@ public void tearDown(SessionFactoryScope scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectEntityFieldHqlExecution(SessionFactoryScope scope) {
|
public void testHqlSelectEntityBasicAttribute(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
final QueryImplementor<String> query = session.createQuery(
|
final QueryImplementor<String> query = session.createQuery(
|
||||||
@ -88,7 +100,7 @@ public void testSelectEntityFieldHqlExecution(SessionFactoryScope scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectGenderHql(SessionFactoryScope scope) {
|
public void testHqlSelectConvertedAttribute(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
final QueryImplementor<Gender> query = session.createQuery(
|
final QueryImplementor<Gender> query = session.createQuery(
|
||||||
@ -103,7 +115,7 @@ public void testSelectGenderHql(SessionFactoryScope scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectEntityHqlExecution(SessionFactoryScope scope) {
|
public void testHqlSelectRootEntity(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
final QueryImplementor<SimpleEntity> query = session.createQuery(
|
final QueryImplementor<SimpleEntity> query = session.createQuery(
|
||||||
@ -117,6 +129,168 @@ public void testSelectEntityHqlExecution(SessionFactoryScope scope) {
|
|||||||
assertThat( simpleEntity.getGender(), is(FEMALE) );
|
assertThat( simpleEntity.getGender(), is(FEMALE) );
|
||||||
assertThat( simpleEntity.getGender2(), is(MALE) );
|
assertThat( simpleEntity.getGender2(), is(MALE) );
|
||||||
assertThat( simpleEntity.getName(), is("Fab") );
|
assertThat( simpleEntity.getName(), is("Fab") );
|
||||||
|
assertThat( simpleEntity.getComponent(), notNullValue() );
|
||||||
|
assertThat( simpleEntity.getComponent().getAttribute1(), is( "a1" ) );
|
||||||
|
assertThat( simpleEntity.getComponent().getAttribute2(), is( "a2" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHqlSelectEmbeddedAttribute(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<Component> query = session.createQuery( "select e.component from SimpleEntity e", Component.class );
|
||||||
|
final Component component = query.uniqueResult();
|
||||||
|
assertThat( component, notNullValue() );
|
||||||
|
assertThat( component.getAttribute1(), is( "a1" ) );
|
||||||
|
assertThat( component.getAttribute2(), is( "a2" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHqlSelectEmbeddableSubAttribute(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<String> query = session.createQuery( "select e.component.attribute1 from SimpleEntity e", String.class );
|
||||||
|
final String attribute1 = query.uniqueResult();
|
||||||
|
assertThat( attribute1, is( "a1" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Dynamic instantiations
|
||||||
|
|
||||||
|
public static class ListItemDto {
|
||||||
|
private String code;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public ListItemDto(String code, String value) {
|
||||||
|
this.code = code;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CategorizedListItemDto {
|
||||||
|
private ListItemDto category;
|
||||||
|
private String code;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public CategorizedListItemDto(ListItemDto category, String code, String value) {
|
||||||
|
this.category = category;
|
||||||
|
this.code = code;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CompoundDto {
|
||||||
|
private ListItemDto first;
|
||||||
|
private ListItemDto second;
|
||||||
|
|
||||||
|
public CompoundDto(ListItemDto first, ListItemDto second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BasicSetterBasedDto {
|
||||||
|
private String code;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHqlBasicDynamicInstantiation(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().inTransaction(
|
||||||
|
session -> {
|
||||||
|
final Query<ListItemDto> query = session.createQuery(
|
||||||
|
"select new ListItemDto( e.component.attribute1, e.name ) from SimpleEntity e",
|
||||||
|
ListItemDto.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final ListItemDto dto = query.getSingleResult();
|
||||||
|
assertThat( dto, notNullValue() );
|
||||||
|
assertThat( dto.code, is( "a1" ) );
|
||||||
|
assertThat( dto.value, is( "Fab" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHqlNestedDynamicInstantiation(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().inTransaction(
|
||||||
|
session -> {
|
||||||
|
final Query<CategorizedListItemDto> query = session.createQuery(
|
||||||
|
"select new CategorizedListItemDto( new ListItemDto( e.component.attribute2, e.component.attribute1 ), e.component.attribute1, e.name ) from SimpleEntity e",
|
||||||
|
CategorizedListItemDto.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final CategorizedListItemDto dto = query.getSingleResult();
|
||||||
|
assertThat( dto, notNullValue() );
|
||||||
|
assertThat( dto.category, notNullValue() );
|
||||||
|
assertThat( dto.category.code, is( "a2") );
|
||||||
|
assertThat( dto.category.value, is( "a1") );
|
||||||
|
assertThat( dto.code, is( "a1" ) );
|
||||||
|
assertThat( dto.value, is( "Fab" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHqlMultipleDynamicInstantiation(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().inTransaction(
|
||||||
|
session -> {
|
||||||
|
final Query<CompoundDto> query = session.createQuery(
|
||||||
|
"select new CompoundDto( new ListItemDto( e.component.attribute1, e.name ), new ListItemDto( e.component.attribute2, e.name ) ) from SimpleEntity e",
|
||||||
|
CompoundDto.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final CompoundDto dto = query.getSingleResult();
|
||||||
|
assertThat( dto, notNullValue() );
|
||||||
|
|
||||||
|
assertThat( dto.first, notNullValue() );
|
||||||
|
assertThat( dto.first.code, is( "a1" ) );
|
||||||
|
assertThat( dto.first.value, is( "Fab" ) );
|
||||||
|
|
||||||
|
assertThat( dto.second, notNullValue() );
|
||||||
|
assertThat( dto.second.code, is( "a2" ) );
|
||||||
|
assertThat( dto.second.value, is( "Fab" ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBasicSetterDynamicInstantiation(SessionFactoryScope scope) {
|
||||||
|
scope.getSessionFactory().inTransaction(
|
||||||
|
session -> {
|
||||||
|
final Query<BasicSetterBasedDto> query = session.createQuery(
|
||||||
|
"select new BasicSetterBasedDto( e.component.attribute1 as code, e.name as value ) from SimpleEntity e",
|
||||||
|
BasicSetterBasedDto.class
|
||||||
|
);
|
||||||
|
|
||||||
|
final BasicSetterBasedDto dto = query.getSingleResult();
|
||||||
|
assertThat( dto, notNullValue() );
|
||||||
|
|
||||||
|
assertThat( dto.code, is( "a1" ) );
|
||||||
|
assertThat( dto.value, is( "Fab" ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -93,4 +93,11 @@
|
|||||||
Class[] annotatedClasses() default {};
|
Class[] annotatedClasses() default {};
|
||||||
String[] annotatedClassNames() default {};
|
String[] annotatedClassNames() default {};
|
||||||
String[] xmlMappings() default {};
|
String[] xmlMappings() default {};
|
||||||
|
ExtraQueryImport[] extraQueryImports() default {};
|
||||||
|
Class<?>[] extraQueryImportClasses() default {};
|
||||||
|
|
||||||
|
@interface ExtraQueryImport {
|
||||||
|
String name();
|
||||||
|
Class<?> importedClass();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,14 @@ public static DomainModelScope findMetamodelScope(Object testInstance, Extension
|
|||||||
metadataSources.addResource( xmlMapping );
|
metadataSources.addResource( xmlMapping );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( DomainModel.ExtraQueryImport extraQueryImport : domainModelAnnotation.extraQueryImports() ) {
|
||||||
|
metadataSources.addQueryImport( extraQueryImport.name(), extraQueryImport.importedClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( Class<?> importedClass : domainModelAnnotation.extraQueryImportClasses() ) {
|
||||||
|
metadataSources.addQueryImport( importedClass.getSimpleName(), importedClass );
|
||||||
|
}
|
||||||
|
|
||||||
return (MetadataImplementor) metadataSources.buildMetadata();
|
return (MetadataImplementor) metadataSources.buildMetadata();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user