parent
076a0aa25a
commit
ca1692b86f
|
@ -151,7 +151,7 @@ public interface MappingModelCreationLogger extends BasicLogger {
|
|||
|90003501
|
||||
|90004000
|
||||
|org.hibernate.orm.query.hql
|
||||
|org.hibernate.query.hql.HqlLogger
|
||||
|org.hibernate.query.hql.HqlLogging
|
||||
|
||||
|90004001
|
||||
|90005000
|
||||
|
|
|
@ -35,6 +35,9 @@ import org.hibernate.engine.spi.ExceptionConverter;
|
|||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.loader.MultipleBagFetchException;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.sqm.InterpretationException;
|
||||
import org.hibernate.query.sqm.ParsingException;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
|
@ -134,9 +137,18 @@ public class ExceptionConverterImpl implements ExceptionConverter {
|
|||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( cause instanceof SemanticException ) {
|
||||
return new IllegalArgumentException( cause );
|
||||
}
|
||||
else if ( cause instanceof QueryException ) {
|
||||
return new IllegalArgumentException( cause );
|
||||
}
|
||||
else if ( cause instanceof InterpretationException ) {
|
||||
return new IllegalArgumentException( cause );
|
||||
}
|
||||
else if ( cause instanceof ParsingException ) {
|
||||
return new IllegalArgumentException( cause );
|
||||
}
|
||||
else if ( cause instanceof MultipleBagFetchException ) {
|
||||
return new IllegalArgumentException( cause );
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.internal.util;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -43,6 +44,14 @@ public class MutableObject<T> {
|
|||
this.reference = reference;
|
||||
}
|
||||
|
||||
public void set(T reference, BiConsumer<T,T> existingConsumer) {
|
||||
if ( this.reference != null ) {
|
||||
existingConsumer.accept( reference, this.reference );
|
||||
}
|
||||
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public void setIfNot(T reference) {
|
||||
if ( this.reference == null ) {
|
||||
this.reference = reference;
|
||||
|
|
|
@ -13,6 +13,11 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
*/
|
||||
public interface EntityDiscriminatorMapping extends VirtualModelPart, BasicValuedModelPart {
|
||||
String ROLE_NAME = "{discriminator}";
|
||||
String LEGACY_HQL_ROLE_NAME = "class";
|
||||
|
||||
static boolean matchesRoleName(String name) {
|
||||
return ROLE_NAME.equals( name ) || LEGACY_HQL_ROLE_NAME.equals( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
default String getPartName() {
|
||||
|
|
|
@ -15,6 +15,7 @@ import javax.persistence.metamodel.ManagedType;
|
|||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
@ -114,4 +115,6 @@ public interface JpaMetamodel extends javax.persistence.metamodel.Metamodel {
|
|||
<T> RootGraphImplementor<T> findEntityGraphByName(String name);
|
||||
|
||||
<T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass);
|
||||
|
||||
JpaCompliance getJpaCompliance();
|
||||
}
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
package org.hibernate.metamodel.model.domain.internal;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
|
||||
|
@ -35,17 +32,7 @@ public class EntitySqmPathSource<J> extends AbstractSqmPathSource<J> {
|
|||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
final EntityDomainType<J> sqmPathType = getSqmPathType();
|
||||
final PersistentAttribute<?,?> attribute = sqmPathType.findAttribute( name );
|
||||
if ( attribute != null ) {
|
||||
return (SqmPathSource<?>) attribute;
|
||||
}
|
||||
|
||||
final SingularPersistentAttribute<J, ?> idAttribute = sqmPathType.findIdAttribute();
|
||||
if ( idAttribute != null && idAttribute.getName().equals( name ) ) {
|
||||
return idAttribute;
|
||||
}
|
||||
|
||||
throw new SemanticException( "Unknown sub-path name : " + name );
|
||||
return sqmPathType.findSubPathSource( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,15 +12,21 @@ import javax.persistence.metamodel.EntityType;
|
|||
import org.hibernate.graph.internal.SubGraphImpl;
|
||||
import org.hibernate.graph.spi.SubGraphImplementor;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.metamodel.model.domain.PersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.IllegalPathUsageException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
|
@ -33,6 +39,7 @@ public class EntityTypeImpl<J>
|
|||
extends AbstractIdentifiableType<J>
|
||||
implements EntityDomainType<J>, Serializable {
|
||||
private final String jpaEntityName;
|
||||
private final SqmPathSource<?> discriminatorPathSource;
|
||||
|
||||
public EntityTypeImpl(
|
||||
JavaTypeDescriptor<J> javaTypeDescriptor,
|
||||
|
@ -50,6 +57,63 @@ public class EntityTypeImpl<J>
|
|||
);
|
||||
|
||||
this.jpaEntityName = persistentClass.getJpaEntityName();
|
||||
|
||||
if ( persistentClass.hasSubclasses() ) {
|
||||
final Value discriminator = persistentClass.getDiscriminator();
|
||||
final DomainType discriminatorType;
|
||||
if ( discriminator != null ) {
|
||||
discriminatorType = (DomainType) discriminator.getType();
|
||||
}
|
||||
else {
|
||||
discriminatorType = StandardBasicTypes.STRING;
|
||||
}
|
||||
|
||||
discriminatorPathSource = new SqmPathSource() {
|
||||
@Override
|
||||
public String getPathName() {
|
||||
return EntityDiscriminatorMapping.ROLE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainType<?> getSqmPathType() {
|
||||
// the BasicType for Class?
|
||||
return discriminatorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> createSqmPath(SqmPath lhs, SqmCreationState creationState) {
|
||||
return new SqmBasicValuedSimplePath(
|
||||
lhs.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
|
||||
this,
|
||||
lhs,
|
||||
creationState.getCreationContext().getNodeBuilder()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BindableType getBindableType() {
|
||||
return BindableType.SINGULAR_ATTRIBUTE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getBindableJavaType() {
|
||||
return getExpressableJavaTypeDescriptor().getJavaType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<?> getExpressableJavaTypeDescriptor() {
|
||||
return discriminatorType.getExpressableJavaTypeDescriptor();
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
discriminatorPathSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -83,6 +147,10 @@ public class EntityTypeImpl<J>
|
|||
// todo (6.0) : probably need special handling here for non-aggregated composite ids
|
||||
}
|
||||
|
||||
if ( EntityDiscriminatorMapping.matchesRoleName( name ) ) {
|
||||
return discriminatorPathSource;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ import org.hibernate.internal.EntityManagerMessageLogger;
|
|||
import org.hibernate.internal.HEMLogging;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.metamodel.internal.InflightRuntimeMetamodel;
|
||||
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
|
||||
import org.hibernate.metamodel.internal.MetadataContext;
|
||||
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
|
||||
|
@ -71,6 +71,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
|
|||
}
|
||||
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
private final JpaCompliance jpaCompliance;
|
||||
|
||||
private final Map<String, EntityDomainType<?>> jpaEntityTypeMap = new ConcurrentHashMap<>();
|
||||
private final Map<Class<?>, MappedSuperclassDomainType<?>> jpaMappedSuperclassTypeMap = new ConcurrentHashMap<>();
|
||||
|
@ -85,8 +86,9 @@ public class JpaMetamodelImpl implements JpaMetamodel {
|
|||
private final Map<String, ImportInfo<?>> nameToImportMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
public JpaMetamodelImpl(TypeConfiguration typeConfiguration) {
|
||||
public JpaMetamodelImpl(TypeConfiguration typeConfiguration, JpaCompliance jpaCompliance) {
|
||||
this.typeConfiguration = typeConfiguration;
|
||||
this.jpaCompliance = jpaCompliance;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,6 +96,11 @@ public class JpaMetamodelImpl implements JpaMetamodel {
|
|||
return typeConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JpaCompliance getJpaCompliance() {
|
||||
return jpaCompliance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> EntityDomainType<X> entity(String entityName) {
|
||||
//noinspection unchecked
|
||||
|
@ -454,25 +461,6 @@ public class JpaMetamodelImpl implements JpaMetamodel {
|
|||
throw new IllegalArgumentException( "Could not resolve entity reference : " + javaType.getName() );
|
||||
}
|
||||
|
||||
public static JpaMetamodel buildMetamodel(
|
||||
RuntimeModelCreationContext runtimeModelCreationContext,
|
||||
MetadataImplementor bootMetamodel,
|
||||
InflightRuntimeMetamodel inflightRuntimeMetamodel,
|
||||
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
|
||||
java.util.Collection<NamedEntityGraphDefinition> namedEntityGraphDefinitions) {
|
||||
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( inflightRuntimeMetamodel.getTypeConfiguration() );
|
||||
|
||||
jpaMetamodel.processJpa(
|
||||
bootMetamodel,
|
||||
inflightRuntimeMetamodel.getEntityProxyInterfaceMap(),
|
||||
jpaStaticMetaModelPopulationSetting,
|
||||
namedEntityGraphDefinitions,
|
||||
runtimeModelCreationContext
|
||||
);
|
||||
|
||||
return jpaMetamodel;
|
||||
}
|
||||
|
||||
public void processJpa(
|
||||
MetadataImplementor bootMetamodel,
|
||||
Map<Class, String> entityProxyInterfaceMap,
|
||||
|
|
|
@ -149,7 +149,7 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
|
|||
public MappingMetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.typeConfiguration = typeConfiguration;
|
||||
this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration );
|
||||
this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, sessionFactory.getSessionFactoryOptions().getJpaCompliance() );
|
||||
}
|
||||
|
||||
public JpaMetamodel getJpaMetamodel() {
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.persistence.TemporalType;
|
|||
import javax.persistence.TransactionRequiredException;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
@ -33,7 +34,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.graph.GraphSemantic;
|
||||
import org.hibernate.graph.RootGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
|
@ -54,6 +54,7 @@ import org.hibernate.query.results.ResultSetMapping;
|
|||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.query.spi.AbstractQuery;
|
||||
import org.hibernate.query.spi.MutableQueryOptions;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||
import org.hibernate.result.NoMoreReturnsException;
|
||||
|
@ -63,8 +64,6 @@ import org.hibernate.result.UpdateCountOutput;
|
|||
import org.hibernate.result.spi.ResultContext;
|
||||
import org.hibernate.sql.results.NoMoreOutputsException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@link org.hibernate.procedure.ProcedureCall}
|
||||
*
|
||||
|
@ -73,10 +72,6 @@ import org.jboss.logging.Logger;
|
|||
public class ProcedureCallImpl<R>
|
||||
extends AbstractQuery<R>
|
||||
implements ProcedureCallImplementor<R>, ResultContext {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
ProcedureCallImpl.class.getName()
|
||||
);
|
||||
|
||||
private final String procedureName;
|
||||
|
||||
|
@ -272,6 +267,11 @@ public class ProcedureCallImpl<R>
|
|||
return queryOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
throw new IllegalStateException( "Cannot set LockMode on a procedure-call" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureParameterMetadataImpl getParameterMetadata() {
|
||||
return parameterMetadata;
|
||||
|
@ -601,21 +601,6 @@ public class ProcedureCallImpl<R>
|
|||
return mementos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canApplyAliasSpecificLockModes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingLockMode() {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a ProcedureCall / StoredProcedureQuery" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingAliasSpecificLockModes() {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a ProcedureCall / StoredProcedureQuery" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyEntityGraphQueryHint(String hintName, RootGraphImplementor entityGraph) {
|
||||
throw new IllegalStateException( "EntityGraph hints are not supported for ProcedureCall/StoredProcedureQuery" );
|
||||
|
|
|
@ -24,10 +24,10 @@ import static org.jboss.logging.Logger.Level.ERROR;
|
|||
*/
|
||||
@MessageLogger( projectCode = "HHH" )
|
||||
@ValidIdRange( min = 90003501, max = 90004000 )
|
||||
public interface HqlLogger extends BasicLogger {
|
||||
public interface HqlLogging extends BasicLogger {
|
||||
String LOGGER_NAME = QueryLogging.subLoggerName( "hql" );
|
||||
|
||||
HqlLogger QUERY_LOGGER = Logger.getMessageLogger( HqlLogger.class, LOGGER_NAME );
|
||||
HqlLogging QUERY_LOGGER = Logger.getMessageLogger( HqlLogging.class, LOGGER_NAME );
|
||||
|
||||
boolean TRACE_ENABLED = QUERY_LOGGER.isTraceEnabled();
|
||||
boolean DEBUG_ENABLED = QUERY_LOGGER.isDebugEnabled();
|
|
@ -9,18 +9,22 @@ package org.hibernate.query.hql.internal;
|
|||
import java.lang.reflect.Field;
|
||||
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
import org.hibernate.query.hql.spi.DotIdentifierConsumer;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.hql.spi.SqmPathRegistry;
|
||||
import org.hibernate.query.sqm.ParsingException;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.spi.SqmCreationContext;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFrom;
|
||||
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
@ -45,8 +49,6 @@ import org.jboss.logging.Logger;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
||||
private static final Logger log = Logger.getLogger( BasicDotIdentifierConsumer.class );
|
||||
|
||||
private final SqmCreationState creationState;
|
||||
|
||||
private String pathSoFar;
|
||||
|
@ -84,7 +86,7 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
pathSoFar += ( '.' + identifier );
|
||||
}
|
||||
|
||||
log.tracef(
|
||||
HqlLogging.QUERY_LOGGER.tracef(
|
||||
"BasicDotIdentifierHandler#consumeIdentifier( %s, %s, %s ) - %s",
|
||||
identifier,
|
||||
isBase,
|
||||
|
@ -112,6 +114,14 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
String identifier,
|
||||
boolean isTerminal,
|
||||
SqmCreationState creationState) {
|
||||
HqlLogging.QUERY_LOGGER.tracef(
|
||||
"BaseLocalSequencePart#consumeIdentifier( %s, %s, %s ) - %s",
|
||||
identifier,
|
||||
isBase,
|
||||
isTerminal,
|
||||
pathSoFar
|
||||
);
|
||||
|
||||
if ( isBase ) {
|
||||
isBase = false;
|
||||
|
||||
|
@ -119,7 +129,7 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
.getCurrent()
|
||||
.getPathRegistry();
|
||||
|
||||
final SqmFrom pathRootByAlias = sqmPathRegistry.findFromByAlias( identifier );
|
||||
final SqmFrom<?,?> pathRootByAlias = sqmPathRegistry.findFromByAlias( identifier );
|
||||
if ( pathRootByAlias != null ) {
|
||||
// identifier is an alias (identification variable)
|
||||
validateAsRoot( pathRootByAlias );
|
||||
|
@ -144,7 +154,7 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
}
|
||||
else {
|
||||
pathRootByExposedNavigable.registerImplicitJoinPath( sqmPath );
|
||||
return new DomainPathPart( pathRootByAlias );
|
||||
return new DomainPathPart( pathRootByExposedNavigable );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,11 +171,19 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
//
|
||||
// todo (6.0) : finish this logic. and see above note in `! isTerminal` block
|
||||
|
||||
final SqmCreationContext creationContext = creationState.getCreationContext();
|
||||
|
||||
if ( ! isTerminal ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final SqmCreationContext creationContext = creationState.getCreationContext();
|
||||
final String importableName = creationContext.getJpaMetamodel().qualifyImportableName( pathSoFar );
|
||||
if ( importableName != null ) {
|
||||
final EntityDomainType<?> entityDomainType = creationContext.getJpaMetamodel().entity( importableName );
|
||||
if ( entityDomainType != null ) {
|
||||
return new SqmLiteralEntityType( entityDomainType, creationContext.getNodeBuilder() );
|
||||
}
|
||||
}
|
||||
|
||||
final SqmFunctionDescriptor functionDescriptor = creationContext.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.hql.internal;
|
|||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.hql.spi.SqmCreationState;
|
||||
|
@ -25,6 +26,7 @@ public class DomainPathPart implements SemanticPathPart {
|
|||
@SuppressWarnings("WeakerAccess")
|
||||
public DomainPathPart(SqmPath<?> basePath) {
|
||||
this.currentPath = basePath;
|
||||
assert currentPath != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +34,11 @@ public class DomainPathPart implements SemanticPathPart {
|
|||
String name,
|
||||
boolean isTerminal,
|
||||
SqmCreationState creationState) {
|
||||
HqlLogging.QUERY_LOGGER.tracef(
|
||||
"Resolving DomainPathPart(%s) sub-part : %s",
|
||||
currentPath,
|
||||
name
|
||||
);
|
||||
final SqmPath<?> lhs = currentPath;
|
||||
final SqmPathSource subPathSource = lhs.getReferencedPathSource().findSubPathSource( name );
|
||||
if ( subPathSource == null ) {
|
||||
|
|
|
@ -8,7 +8,7 @@ package org.hibernate.query.hql.internal;
|
|||
|
||||
import org.hibernate.grammars.hql.HqlLexer;
|
||||
import org.hibernate.grammars.hql.HqlParser;
|
||||
import org.hibernate.query.hql.HqlLogger;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -22,7 +22,7 @@ import org.antlr.v4.runtime.Token;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class HqlParseTreeBuilder {
|
||||
private static final Logger LOGGER = HqlLogger.subLogger( "reservedWordAsIdentifier" );
|
||||
private static final Logger LOGGER = HqlLogging.subLogger( "reservedWordAsIdentifier" );
|
||||
private static final boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
|
||||
|
||||
/**
|
||||
|
|
|
@ -474,7 +474,7 @@ public class QuerySplitter {
|
|||
@Override
|
||||
public SqmEmptinessPredicate visitIsEmptyPredicate(SqmEmptinessPredicate predicate) {
|
||||
return new SqmEmptinessPredicate(
|
||||
(SqmPath) predicate.getPluralPath().accept( this ),
|
||||
(SqmPluralValuedSimplePath<?>) predicate.getPluralPath().accept( this ),
|
||||
predicate.isNegated(),
|
||||
predicate.nodeBuilder()
|
||||
);
|
||||
|
@ -483,7 +483,7 @@ public class QuerySplitter {
|
|||
@Override
|
||||
public SqmNullnessPredicate visitIsNullPredicate(SqmNullnessPredicate predicate) {
|
||||
return new SqmNullnessPredicate(
|
||||
(SqmExpression) predicate.getExpression().accept( this ),
|
||||
(SqmExpression<?>) predicate.getExpression().accept( this ),
|
||||
predicate.isNegated(),
|
||||
predicate.nodeBuilder()
|
||||
);
|
||||
|
@ -492,9 +492,9 @@ public class QuerySplitter {
|
|||
@Override
|
||||
public SqmBetweenPredicate visitBetweenPredicate(SqmBetweenPredicate predicate) {
|
||||
return new SqmBetweenPredicate(
|
||||
(SqmExpression) predicate.getExpression().accept( this ),
|
||||
(SqmExpression) predicate.getLowerBound().accept( this ),
|
||||
(SqmExpression) predicate.getUpperBound().accept( this ),
|
||||
(SqmExpression<?>) predicate.getExpression().accept( this ),
|
||||
(SqmExpression<?>) predicate.getLowerBound().accept( this ),
|
||||
(SqmExpression<?>) predicate.getUpperBound().accept( this ),
|
||||
predicate.isNegated(),
|
||||
predicate.nodeBuilder()
|
||||
);
|
||||
|
@ -503,9 +503,9 @@ public class QuerySplitter {
|
|||
@Override
|
||||
public SqmLikePredicate visitLikePredicate(SqmLikePredicate predicate) {
|
||||
return new SqmLikePredicate(
|
||||
(SqmExpression) predicate.getMatchExpression().accept( this ),
|
||||
(SqmExpression) predicate.getPattern().accept( this ),
|
||||
(SqmExpression) predicate.getEscapeCharacter().accept( this ),
|
||||
(SqmExpression<?>) predicate.getMatchExpression().accept( this ),
|
||||
(SqmExpression<?>) predicate.getPattern().accept( this ),
|
||||
(SqmExpression<?>) predicate.getEscapeCharacter().accept( this ),
|
||||
predicate.nodeBuilder()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.NullPrecedence;
|
||||
import org.hibernate.QueryException;
|
||||
|
@ -58,7 +57,7 @@ import org.hibernate.query.SemanticException;
|
|||
import org.hibernate.query.TemporalUnit;
|
||||
import org.hibernate.query.TrimSpec;
|
||||
import org.hibernate.query.UnaryArithmeticOperator;
|
||||
import org.hibernate.query.hql.HqlLogger;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
import org.hibernate.query.hql.spi.DotIdentifierConsumer;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmCreationOptions;
|
||||
|
@ -76,6 +75,7 @@ import org.hibernate.query.sqm.UnknownEntityException;
|
|||
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.internal.ParameterCollector;
|
||||
import org.hibernate.query.sqm.internal.SqmCreationProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.internal.SqmDmlCreationProcessingState;
|
||||
import org.hibernate.query.sqm.internal.SqmQuerySpecCreationProcessingStateStandardImpl;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
|
@ -92,6 +92,7 @@ import org.hibernate.query.sqm.tree.domain.SqmMaxIndexPath;
|
|||
import org.hibernate.query.sqm.tree.domain.SqmMinElementPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMinIndexPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||
|
@ -164,6 +165,7 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE;
|
||||
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
|
||||
|
@ -171,7 +173,17 @@ import static java.util.Arrays.asList;
|
|||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.hibernate.grammars.hql.HqlParser.IDENTIFIER;
|
||||
import static org.hibernate.query.TemporalUnit.*;
|
||||
import static org.hibernate.query.TemporalUnit.DATE;
|
||||
import static org.hibernate.query.TemporalUnit.DAY_OF_MONTH;
|
||||
import static org.hibernate.query.TemporalUnit.DAY_OF_WEEK;
|
||||
import static org.hibernate.query.TemporalUnit.DAY_OF_YEAR;
|
||||
import static org.hibernate.query.TemporalUnit.NANOSECOND;
|
||||
import static org.hibernate.query.TemporalUnit.OFFSET;
|
||||
import static org.hibernate.query.TemporalUnit.TIME;
|
||||
import static org.hibernate.query.TemporalUnit.TIMEZONE_HOUR;
|
||||
import static org.hibernate.query.TemporalUnit.TIMEZONE_MINUTE;
|
||||
import static org.hibernate.query.TemporalUnit.WEEK_OF_MONTH;
|
||||
import static org.hibernate.query.TemporalUnit.WEEK_OF_YEAR;
|
||||
import static org.hibernate.type.descriptor.DateTimeUtils.DATE_TIME;
|
||||
import static org.hibernate.type.spi.TypeConfiguration.isJdbcTemporalType;
|
||||
|
||||
|
@ -310,7 +322,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
|
||||
final SqmRoot<?> root = new SqmRoot<>(
|
||||
visitEntityName( ctx.dmlTarget().entityName() ),
|
||||
visitIdentificationVariableDef( ctx.dmlTarget().identificationVariableDef() ),
|
||||
applyJpaCompliance( visitIdentificationVariableDef( ctx.dmlTarget().identificationVariableDef() ) ),
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
|
||||
|
@ -323,16 +335,27 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
);
|
||||
|
||||
processingStateStack.push( processingState );
|
||||
processingState.getPathRegistry().register( root );
|
||||
|
||||
try {
|
||||
insertStatement.setSelectQuerySpec( visitQuerySpec( ctx.querySpec() ) );
|
||||
|
||||
final SqmCreationProcessingState stateFieldsProcessingState = new SqmCreationProcessingStateImpl(
|
||||
insertStatement,
|
||||
this
|
||||
);
|
||||
stateFieldsProcessingState.getPathRegistry().register( root );
|
||||
|
||||
processingStateStack.push( stateFieldsProcessingState );
|
||||
try {
|
||||
for ( HqlParser.DotIdentifierSequenceContext stateFieldCtx : ctx.targetFieldsSpec().dotIdentifierSequence() ) {
|
||||
final SqmPath stateField = (SqmPath) visitDotIdentifierSequence( stateFieldCtx );
|
||||
// todo : validate each resolved stateField...
|
||||
insertStatement.addInsertTargetStateField( stateField );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
processingStateStack.pop();
|
||||
}
|
||||
|
||||
return insertStatement;
|
||||
}
|
||||
|
@ -560,7 +583,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
|
||||
@Override
|
||||
public SqmSelection visitSelection(HqlParser.SelectionContext ctx) {
|
||||
final String resultIdentifier = visitResultIdentifier( ctx.resultIdentifier() );
|
||||
final String resultIdentifier = applyJpaCompliance( visitResultIdentifier( ctx.resultIdentifier() ) );
|
||||
final SqmSelectableNode selectableNode = visitSelectableNode( ctx );
|
||||
|
||||
//noinspection unchecked
|
||||
|
@ -746,7 +769,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
}
|
||||
if ( sortExpression instanceof SqmLiteral
|
||||
|| sortExpression instanceof SqmParameter ) {
|
||||
HqlLogger.QUERY_LOGGER.debugf( "Questionable sorting by constant value : %s", sortExpression );
|
||||
HqlLogging.QUERY_LOGGER.debugf( "Questionable sorting by constant value : %s", sortExpression );
|
||||
}
|
||||
|
||||
final String collation;
|
||||
|
@ -935,14 +958,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
public SqmRoot visitPathRoot(HqlParser.PathRootContext ctx) {
|
||||
final String name = ctx.entityName().fullNameText;
|
||||
|
||||
log.debugf( "Handling root path - %s", name );
|
||||
|
||||
final EntityDomainType entityDescriptor = getCreationContext().getJpaMetamodel().resolveHqlEntityReference(
|
||||
name
|
||||
);
|
||||
final EntityDomainType entityDescriptor = getCreationContext()
|
||||
.getJpaMetamodel()
|
||||
.resolveHqlEntityReference( name );
|
||||
|
||||
checkFQNEntityNameJpaComplianceViolationIfNeeded( name, entityDescriptor );
|
||||
|
||||
|
@ -962,15 +986,12 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
}
|
||||
}
|
||||
|
||||
final String alias = visitIdentificationVariableDef( ctx.identificationVariableDef() );
|
||||
|
||||
//noinspection unchecked
|
||||
final SqmRoot sqmRoot = new SqmRoot(
|
||||
entityDescriptor,
|
||||
alias,
|
||||
creationContext.getNodeBuilder()
|
||||
final String alias = applyJpaCompliance(
|
||||
visitIdentificationVariableDef( ctx.identificationVariableDef() )
|
||||
);
|
||||
|
||||
final SqmRoot sqmRoot = new SqmRoot( entityDescriptor, alias, creationContext.getNodeBuilder() );
|
||||
|
||||
processingStateStack.getCurrent().getPathRegistry().register( sqmRoot );
|
||||
|
||||
return sqmRoot;
|
||||
|
@ -1009,6 +1030,18 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
return null;
|
||||
}
|
||||
|
||||
private String applyJpaCompliance(String text) {
|
||||
if ( text == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
||||
return text.toLowerCase( Locale.getDefault() );
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SqmCrossJoin visitCrossJoin(HqlParser.CrossJoinContext ctx) {
|
||||
throw new UnsupportedOperationException( "Unexpected call to #visitCrossJoin, see #consumeCrossJoin" );
|
||||
|
@ -1217,7 +1250,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
|
|||
@Override
|
||||
public SqmEmptinessPredicate visitIsEmptyPredicate(HqlParser.IsEmptyPredicateContext ctx) {
|
||||
return new SqmEmptinessPredicate(
|
||||
(SqmPath) ctx.expression().accept( this ),
|
||||
(SqmPluralValuedSimplePath<?>) ctx.expression().accept( this ),
|
||||
ctx.NOT() != null,
|
||||
creationContext.getNodeBuilder()
|
||||
);
|
||||
|
|
|
@ -12,8 +12,9 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.jpa.spi.JpaCompliance;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.hql.HqlLogger;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
|
||||
import org.hibernate.query.hql.spi.SqmPathRegistry;
|
||||
import org.hibernate.query.sqm.AliasCollisionException;
|
||||
|
@ -31,6 +32,7 @@ import org.hibernate.query.sqm.tree.select.SqmSelection;
|
|||
*/
|
||||
public class SqmPathRegistryImpl implements SqmPathRegistry {
|
||||
private final SqmCreationProcessingState associatedProcessingState;
|
||||
private final JpaCompliance jpaCompliance;
|
||||
|
||||
private final Map<NavigablePath, SqmPath> sqmPathByPath = new HashMap<>();
|
||||
private final Map<NavigablePath, SqmFrom> sqmFromByPath = new HashMap<>();
|
||||
|
@ -41,6 +43,7 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
|
||||
public SqmPathRegistryImpl(SqmCreationProcessingState associatedProcessingState) {
|
||||
this.associatedProcessingState = associatedProcessingState;
|
||||
this.jpaCompliance = associatedProcessingState.getCreationState().getCreationContext().getJpaMetamodel().getJpaCompliance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -60,7 +63,12 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
|
||||
final String alias = sqmPath.getExplicitAlias();
|
||||
if ( alias != null ) {
|
||||
final SqmFrom previousFrom = sqmFromByAlias.put( alias, sqmFrom );
|
||||
final String aliasToUse = jpaCompliance.isJpaQueryComplianceEnabled()
|
||||
? alias.toLowerCase( Locale.getDefault() )
|
||||
: alias;
|
||||
|
||||
final SqmFrom previousFrom = sqmFromByAlias.put( aliasToUse, sqmFrom );
|
||||
|
||||
if ( previousFrom != null ) {
|
||||
throw new AliasCollisionException(
|
||||
String.format(
|
||||
|
@ -148,7 +156,12 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
|
||||
@Override
|
||||
public SqmFrom findFromByAlias(String alias) {
|
||||
final SqmFrom registered = sqmFromByAlias.get( alias );
|
||||
final String localAlias = jpaCompliance.isJpaQueryComplianceEnabled()
|
||||
? alias.toLowerCase( Locale.getDefault() )
|
||||
: alias;
|
||||
|
||||
final SqmFrom registered = sqmFromByAlias.get( localAlias );
|
||||
|
||||
if ( registered != null ) {
|
||||
return registered;
|
||||
}
|
||||
|
@ -167,10 +180,11 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
// (configurable?) option would be to simply pick the first one as a perf optimization
|
||||
|
||||
SqmFrom found = null;
|
||||
for ( SqmFrom fromElement : sqmFromByPath.values() ) {
|
||||
for ( Map.Entry<NavigablePath, SqmFrom> entry : sqmFromByPath.entrySet() ) {
|
||||
final SqmFrom fromElement = entry.getValue();
|
||||
if ( definesAttribute( fromElement.getReferencedPathSource(), navigableName ) ) {
|
||||
if ( found != null ) {
|
||||
// throw new IllegalStateException( "Multiple from-elements expose unqualified attribute : " + navigableName );
|
||||
throw new IllegalStateException( "Multiple from-elements expose unqualified attribute : " + navigableName );
|
||||
}
|
||||
found = fromElement;
|
||||
}
|
||||
|
@ -178,7 +192,7 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
|
||||
if ( found == null ) {
|
||||
if ( associatedProcessingState.getParentProcessingState() != null ) {
|
||||
HqlLogger.QUERY_LOGGER.debugf(
|
||||
HqlLogging.QUERY_LOGGER.debugf(
|
||||
"Unable to resolve unqualified attribute [%s] in local from-clause; checking parent ",
|
||||
navigableName
|
||||
);
|
||||
|
@ -186,6 +200,11 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
|||
}
|
||||
}
|
||||
|
||||
HqlLogging.QUERY_LOGGER.debugf(
|
||||
"Unable to resolve unqualified attribute [%s] in local from-clause",
|
||||
navigableName
|
||||
);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ package org.hibernate.query.hql.internal;
|
|||
import org.hibernate.QueryException;
|
||||
import org.hibernate.grammars.hql.HqlLexer;
|
||||
import org.hibernate.grammars.hql.HqlParser;
|
||||
import org.hibernate.query.hql.HqlLogger;
|
||||
import org.hibernate.query.hql.HqlLogging;
|
||||
import org.hibernate.query.sqm.InterpretationException;
|
||||
import org.hibernate.query.hql.HqlTranslator;
|
||||
import org.hibernate.query.sqm.internal.SqmTreePrinter;
|
||||
|
@ -42,7 +42,7 @@ public class StandardHqlTranslator implements HqlTranslator {
|
|||
|
||||
@Override
|
||||
public SqmStatement translate(String query) {
|
||||
HqlLogger.QUERY_LOGGER.debugf( "HQL : " + query );
|
||||
HqlLogging.QUERY_LOGGER.debugf( "HQL : " + query );
|
||||
|
||||
final HqlParser.StatementContext hqlParseTree = parseHql( query );
|
||||
|
||||
|
|
|
@ -89,5 +89,4 @@ public interface SqmPathRegistry {
|
|||
* Find an SqmSelection by its position in the SqmSelectClause
|
||||
*/
|
||||
SqmSelection findSelectionByPosition(int position);
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -50,6 +51,10 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
return resultBuilders == null ? 0 : resultBuilders.size();
|
||||
}
|
||||
|
||||
public List<ResultBuilder> getResultBuilders() {
|
||||
return Collections.unmodifiableList( resultBuilders );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResultBuilders(BiConsumer<Integer, ResultBuilder> resultBuilderConsumer) {
|
||||
if ( resultBuilders == null ) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
|
@ -22,7 +23,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqlSelectionImpl implements SqlSelection, Expression {
|
||||
public class SqlSelectionImpl implements SqlSelection, Expression, SqlExpressionAccess {
|
||||
private final int valuesArrayPosition;
|
||||
private final BasicValuedMapping valueMapping;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
@ -68,4 +69,9 @@ public class SqlSelectionImpl implements SqlSelection, Expression {
|
|||
public void accept(SqlAstWalker sqlAstWalker) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression getSqlExpression() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.hibernate.property.access.spi.Getter;
|
|||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.IllegalQueryOperationException;
|
||||
import org.hibernate.query.ParameterMetadata;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
import org.hibernate.query.ResultListTransformer;
|
||||
import org.hibernate.query.TupleTransformer;
|
||||
|
@ -67,6 +68,9 @@ import org.hibernate.query.named.NamedQueryMemento;
|
|||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
import static org.hibernate.LockMode.UPGRADE;
|
||||
import static org.hibernate.LockOptions.NONE;
|
||||
import static org.hibernate.LockOptions.READ;
|
||||
import static org.hibernate.LockOptions.WAIT_FOREVER;
|
||||
import static org.hibernate.cfg.AvailableSettings.JPA_LOCK_SCOPE;
|
||||
import static org.hibernate.cfg.AvailableSettings.JPA_LOCK_TIMEOUT;
|
||||
|
@ -143,12 +147,6 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
return session;
|
||||
}
|
||||
|
||||
protected abstract boolean canApplyAliasSpecificLockModes();
|
||||
|
||||
protected abstract void verifySettingLockMode();
|
||||
|
||||
protected abstract void verifySettingAliasSpecificLockModes();
|
||||
|
||||
protected abstract QueryParameterBindings getQueryParameterBindings();
|
||||
|
||||
@Override
|
||||
|
@ -164,27 +162,44 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public int getMaxResults() {
|
||||
getSession().checkOpen();
|
||||
return getQueryOptions().getLimit().getMaxRowsJpa();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setMaxResults(int maxResult) {
|
||||
if ( maxResult < 0 ) {
|
||||
throw new IllegalArgumentException( "max-results cannot be negative" );
|
||||
}
|
||||
|
||||
getSession().checkOpen();
|
||||
|
||||
getQueryOptions().getLimit().setMaxRows( maxResult );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstResult() {
|
||||
getSession().checkOpen();
|
||||
return getQueryOptions().getLimit().getFirstRowJpa();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setFirstResult(int startPosition) {
|
||||
getSession().checkOpen();
|
||||
|
||||
if ( startPosition < 0 ) {
|
||||
throw new IllegalArgumentException( "first-result value cannot be negative : " + startPosition );
|
||||
}
|
||||
|
||||
getQueryOptions().getLimit().setFirstRow( startPosition );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "rawtypes" )
|
||||
public QueryImplementor<R> setTupleTransformer(TupleTransformer transformer) {
|
||||
getQueryOptions().setTupleTransformer( transformer );
|
||||
return this;
|
||||
|
@ -196,25 +211,20 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockModeType getLockMode() {
|
||||
return LockModeTypeHelper.getLockModeType( getQueryOptions().getLockOptions().getLockMode() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlushMode getHibernateFlushMode() {
|
||||
return getQueryOptions().getFlushMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setHibernateFlushMode(FlushMode flushMode) {
|
||||
public QueryImplementor<R> setHibernateFlushMode(FlushMode flushMode) {
|
||||
getQueryOptions().setFlushMode( flushMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlushModeType getFlushMode() {
|
||||
getSession().checkOpen();
|
||||
final FlushMode flushMode = getQueryOptions().getFlushMode() == null
|
||||
? getSession().getHibernateFlushMode()
|
||||
: getQueryOptions().getFlushMode();
|
||||
|
@ -222,8 +232,8 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setFlushMode(FlushModeType flushModeType) {
|
||||
public QueryImplementor<R> setFlushMode(FlushModeType flushModeType) {
|
||||
getSession().checkOpen();
|
||||
setHibernateFlushMode( FlushModeTypeHelper.getFlushMode( flushModeType ) );
|
||||
return this;
|
||||
}
|
||||
|
@ -234,8 +244,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setCacheMode(CacheMode cacheMode) {
|
||||
public QueryImplementor<R> setCacheMode(CacheMode cacheMode) {
|
||||
getQueryOptions().setCacheMode( cacheMode );
|
||||
return this;
|
||||
}
|
||||
|
@ -246,8 +255,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setCacheable(boolean cacheable) {
|
||||
public QueryImplementor<R> setCacheable(boolean cacheable) {
|
||||
getQueryOptions().setResultCachingEnabled( cacheable );
|
||||
return this;
|
||||
}
|
||||
|
@ -258,8 +266,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setCacheRegion(String cacheRegion) {
|
||||
public QueryImplementor<R> setCacheRegion(String cacheRegion) {
|
||||
getQueryOptions().setResultCacheRegionName( cacheRegion );
|
||||
return this;
|
||||
}
|
||||
|
@ -270,8 +277,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setTimeout(int timeout) {
|
||||
public QueryImplementor<R> setTimeout(int timeout) {
|
||||
getQueryOptions().setTimeout( timeout );
|
||||
return this;
|
||||
}
|
||||
|
@ -282,8 +288,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setFetchSize(int fetchSize) {
|
||||
public QueryImplementor<R> setFetchSize(int fetchSize) {
|
||||
getQueryOptions().setFetchSize( fetchSize );
|
||||
return this;
|
||||
}
|
||||
|
@ -296,8 +301,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setReadOnly(boolean readOnly) {
|
||||
public QueryImplementor<R> setReadOnly(boolean readOnly) {
|
||||
getQueryOptions().setReadOnly( readOnly );
|
||||
return this;
|
||||
}
|
||||
|
@ -308,8 +312,14 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setLockOptions(LockOptions lockOptions) {
|
||||
public LockModeType getLockMode() {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
return LockModeTypeHelper.getLockModeType( getQueryOptions().getLockOptions().getLockMode() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
getQueryOptions().getLockOptions().setLockMode( lockOptions.getLockMode() );
|
||||
getQueryOptions().getLockOptions().setScope( lockOptions.getScope() );
|
||||
getQueryOptions().getLockOptions().setTimeOut( lockOptions.getTimeOut() );
|
||||
|
@ -318,23 +328,14 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setLockMode(String alias, LockMode lockMode) {
|
||||
if ( !LockMode.NONE.equals( lockMode ) ) {
|
||||
verifySettingAliasSpecificLockModes();
|
||||
}
|
||||
|
||||
public QueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
getQueryOptions().getLockOptions().setAliasSpecificLockMode( alias, lockMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setLockMode(LockModeType lockModeType) {
|
||||
if ( !LockModeType.NONE.equals( lockModeType ) ) {
|
||||
verifySettingLockMode();
|
||||
}
|
||||
|
||||
public QueryImplementor<R> setLockMode(LockModeType lockModeType) {
|
||||
getSession().checkOpen();
|
||||
getQueryOptions().getLockOptions().setLockMode( LockModeTypeHelper.getLockMode( lockModeType ) );
|
||||
return this;
|
||||
}
|
||||
|
@ -345,15 +346,13 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setComment(String comment) {
|
||||
public QueryImplementor<R> setComment(String comment) {
|
||||
getQueryOptions().setComment( comment );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor addQueryHint(String hint) {
|
||||
public QueryImplementor<R> addQueryHint(String hint) {
|
||||
getQueryOptions().addDatabaseHint( hint );
|
||||
return this;
|
||||
}
|
||||
|
@ -375,16 +374,10 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
getSession().checkOpen( false );
|
||||
|
||||
final Map<String,Object> hints = new HashMap<>();
|
||||
collectBaselineHints( hints );
|
||||
collectHints( hints );
|
||||
return hints;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected void collectBaselineHints(Map<String, Object> hints) {
|
||||
// nothing to do in this form
|
||||
}
|
||||
|
||||
protected void collectHints(Map<String, Object> hints) {
|
||||
if ( getQueryOptions().getTimeout() != null ) {
|
||||
hints.put( HINT_TIMEOUT, getQueryOptions().getTimeout() );
|
||||
|
@ -428,7 +421,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
}
|
||||
|
||||
protected void putIfNotNull(Map<String, Object> hints, String hintName, Enum hintValue) {
|
||||
protected void putIfNotNull(Map<String, Object> hints, String hintName, Enum<?> hintValue) {
|
||||
// centralized spot to handle the decision whether to put enums directly into the hints map
|
||||
// or whether to put the enum name
|
||||
if ( hintValue != null ) {
|
||||
|
@ -446,6 +439,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
@Override
|
||||
public QueryImplementor<R> setHint(String hintName, Object value) {
|
||||
getSession().checkOpen( true );
|
||||
|
||||
boolean applied = false;
|
||||
try {
|
||||
if ( HINT_TIMEOUT.equals( hintName ) ) {
|
||||
|
@ -492,27 +486,22 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
applied = applyNativeQueryLockMode( value );
|
||||
}
|
||||
else if ( hintName.startsWith( ALIAS_SPECIFIC_LOCK_MODE ) ) {
|
||||
if ( canApplyAliasSpecificLockModes() ) {
|
||||
// extract the alias
|
||||
final String alias = hintName.substring( ALIAS_SPECIFIC_LOCK_MODE.length() + 1 );
|
||||
// determine the LockMode
|
||||
try {
|
||||
final LockMode lockMode = LockModeTypeHelper.interpretLockMode( value );
|
||||
applyAliasSpecificLockModeHint( alias, lockMode );
|
||||
applied = true;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
log.unableToDetermineLockModeValue( hintName, value );
|
||||
applied = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//noinspection ConstantConditions
|
||||
applied = false;
|
||||
}
|
||||
}
|
||||
else if ( HINT_FETCHGRAPH.equals( hintName ) || HINT_LOADGRAPH.equals( hintName ) ) {
|
||||
if (value instanceof RootGraphImplementor ) {
|
||||
applyEntityGraphQueryHint( hintName, (RootGraphImplementor) value );
|
||||
applyEntityGraphQueryHint( hintName, (RootGraphImplementor<?>) value );
|
||||
}
|
||||
else {
|
||||
log.warnf( "The %s hint was set, but the value was not an EntityGraph!", hintName );
|
||||
|
@ -682,29 +671,34 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings( "UnusedReturnValue" )
|
||||
protected boolean applyLockModeTypeHint(LockModeType lockModeType) {
|
||||
getLockOptions().setLockMode( LockModeTypeHelper.getLockMode( lockModeType ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings( "UnusedReturnValue" )
|
||||
protected boolean applyHibernateLockModeHint(LockMode lockMode) {
|
||||
getLockOptions().setLockMode( lockMode );
|
||||
final LockOptions lockOptions;
|
||||
if ( lockMode == LockMode.NONE ) {
|
||||
lockOptions = NONE;
|
||||
}
|
||||
else if ( lockMode == LockMode.READ ) {
|
||||
lockOptions = READ;
|
||||
}
|
||||
else if ( lockMode == UPGRADE || lockMode == LockMode.PESSIMISTIC_WRITE ) {
|
||||
lockOptions = LockOptions.UPGRADE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the alias specific lock modes. Assumes {@link #canApplyAliasSpecificLockModes()} has already been
|
||||
* called and returned {@code true}.
|
||||
*
|
||||
* @param alias The alias to apply the 'lockMode' to.
|
||||
* @param lockMode The LockMode to apply.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected void applyAliasSpecificLockModeHint(String alias, LockMode lockMode) {
|
||||
getLockOptions().setAliasSpecificLockMode( alias, lockMode );
|
||||
setLockMode( alias, lockMode );
|
||||
}
|
||||
|
||||
protected abstract void applyEntityGraphQueryHint(String hintName, RootGraphImplementor entityGraph);
|
||||
protected abstract void applyEntityGraphQueryHint(String hintName, RootGraphImplementor<?> entityGraph);
|
||||
|
||||
/**
|
||||
* Apply the follow-on-locking hint.
|
||||
|
@ -719,19 +713,20 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// QueryParameter handling
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public Set<Parameter<?>> getParameters() {
|
||||
getSession().checkOpen( false );
|
||||
return (Set) ( (ParameterMetadata) getParameterMetadata() ).getRegistrations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parameter<?> getParameter(String name) {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
try {
|
||||
return getParameterMetadata().getQueryParameter( name );
|
||||
}
|
||||
|
@ -743,7 +738,10 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Parameter<T> getParameter(String name, Class<T> type) {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
try {
|
||||
//noinspection rawtypes
|
||||
final QueryParameter parameter = getParameterMetadata().getQueryParameter( name );
|
||||
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -761,6 +759,8 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public Parameter<?> getParameter(int position) {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
try {
|
||||
return getParameterMetadata().getQueryParameter( position );
|
||||
}
|
||||
|
@ -770,8 +770,10 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public <T> Parameter<T> getParameter(int position, Class<T> type) {
|
||||
getSession().checkOpen( false );
|
||||
|
||||
try {
|
||||
final QueryParameter parameter = getParameterMetadata().getQueryParameter( position );
|
||||
if ( !parameter.getParameterType().isAssignableFrom( type ) ) {
|
||||
|
@ -790,14 +792,15 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public boolean isBound(Parameter<?> param) {
|
||||
final QueryParameterImplementor qp = getParameterMetadata().resolve( param );
|
||||
getSession().checkOpen();
|
||||
|
||||
final QueryParameterImplementor<?> qp = getParameterMetadata().resolve( param );
|
||||
return qp != null && getQueryParameterBindings().isBound( qp );
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@SuppressWarnings( {"WeakerAccess", "unchecked", "rawtypes"} )
|
||||
protected <P> QueryParameterBinding<P> locateBinding(Parameter<P> parameter) {
|
||||
if ( parameter instanceof QueryParameterImplementor ) {
|
||||
//noinspection unchecked
|
||||
return locateBinding( (QueryParameterImplementor) parameter );
|
||||
}
|
||||
else if ( parameter.getName() != null ) {
|
||||
|
@ -814,20 +817,20 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected <P> QueryParameterBinding<P> locateBinding(QueryParameterImplementor<P> parameter) {
|
||||
//noinspection unchecked
|
||||
getSession().checkOpen();
|
||||
return getQueryParameterBindings().getBinding( parameter );
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
|
||||
protected <P> QueryParameterBinding<P> locateBinding(String name) {
|
||||
//noinspection unchecked
|
||||
return (QueryParameterBinding) getQueryParameterBindings().getBinding( name );
|
||||
getSession().checkOpen();
|
||||
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( name );
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@SuppressWarnings( {"WeakerAccess", "unchecked"} )
|
||||
protected <P> QueryParameterBinding<P> locateBinding(int position) {
|
||||
//noinspection unchecked
|
||||
return (QueryParameterBinding) getQueryParameterBindings().getBinding( position );
|
||||
getSession().checkOpen();
|
||||
return (QueryParameterBinding<P>) getQueryParameterBindings().getBinding( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -920,7 +923,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
private <P> void setParameter(Parameter<P> parameter, Object value, AllowableParameterType type) {
|
||||
if ( parameter instanceof QueryParameter ) {
|
||||
setParameter( (QueryParameter) parameter, value, type );
|
||||
|
@ -943,6 +946,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
setParameter( name, typedValueWrapper.getValue(), typedValueWrapper.getType() );
|
||||
}
|
||||
else if ( value instanceof Collection ) {
|
||||
//noinspection rawtypes
|
||||
setParameterList( name, (Collection) value );
|
||||
}
|
||||
else {
|
||||
|
@ -958,7 +962,9 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
final TypedParameterValue typedParameterValue = (TypedParameterValue) value;
|
||||
setParameter( position, typedParameterValue.getValue(), typedParameterValue.getType() );
|
||||
}
|
||||
|
||||
if ( value instanceof Collection ) {
|
||||
//noinspection rawtypes
|
||||
setParameterList( Integer.toString( position ), (Collection) value );
|
||||
}
|
||||
else {
|
||||
|
@ -968,21 +974,21 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public <P> QueryImplementor<R> setParameter(QueryParameter<P> parameter, P value, AllowableParameterType type) {
|
||||
locateBinding( parameter ).setBindValue( value, type );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameter(String name, Object value, AllowableParameterType type) {
|
||||
locateBinding( name ).setBindValue( value, type );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor setParameter(int position, Object value, AllowableParameterType type) {
|
||||
locateBinding( position ).setBindValue( value, type );
|
||||
return this;
|
||||
|
@ -1012,29 +1018,29 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public QueryImplementor setParameterList(String name, Collection values) {
|
||||
@SuppressWarnings( {"rawtypes", "unchecked"} )
|
||||
public QueryImplementor<R> setParameterList(String name, Collection values) {
|
||||
locateBinding( name ).setBindValues( values );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(int position, Collection values) {
|
||||
locateBinding( position ).setBindValues( values );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(String name, Collection values, AllowableParameterType type) {
|
||||
locateBinding( name ).setBindValues( values, type );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(int position, Collection values, AllowableParameterType type) {
|
||||
locateBinding( position ).setBindValues( values, type );
|
||||
return this;
|
||||
|
@ -1053,21 +1059,21 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(String name, Object[] values, AllowableParameterType type) {
|
||||
locateBinding( name ).setBindValues( Arrays.asList( values ), type );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(int position, Object[] values, AllowableParameterType type) {
|
||||
locateBinding( position ).setBindValues( Arrays.asList( values ), type );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(String name, Collection values, Class javaType) {
|
||||
final JavaTypeDescriptor javaDescriptor = getSession().getFactory()
|
||||
.getTypeConfiguration()
|
||||
|
@ -1102,7 +1108,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameterList(int position, Collection values, Class javaType) {
|
||||
final JavaTypeDescriptor javaDescriptor = getSession().getFactory()
|
||||
.getTypeConfiguration()
|
||||
|
@ -1137,14 +1143,14 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameter(Parameter<Calendar> param, Calendar value, TemporalType temporalType) {
|
||||
locateBinding( (QueryParameter) param ).setBindValue( value, temporalType );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public QueryImplementor<R> setParameter(Parameter<Date> param, Date value, TemporalType temporalType) {
|
||||
locateBinding( (QueryParameter) param ).setBindValue( value, temporalType );
|
||||
return this;
|
||||
|
@ -1175,8 +1181,10 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public <T> T getParameterValue(Parameter<T> param) {
|
||||
QueryLogging.QUERY_LOGGER.tracef( "#getParameterValue(%s)", param );
|
||||
|
||||
final QueryParameterImplementor qp = getParameterMetadata().resolve( param );
|
||||
if ( qp == null ) {
|
||||
throw new IllegalArgumentException( "The parameter [" + param + "] is not part of this Query" );
|
||||
|
@ -1184,7 +1192,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
final QueryParameterBinding binding = getQueryParameterBindings().getBinding( qp );
|
||||
if ( binding == null || !binding.isBound() ) {
|
||||
throw new IllegalStateException( "The parameter [" + param + "] has not yet been bound" );
|
||||
throw new IllegalStateException( "Parameter value not yet bound : " + param.toString() );
|
||||
}
|
||||
|
||||
if ( binding.isMultiValued() ) {
|
||||
|
@ -1197,14 +1205,14 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public Object getParameterValue(String name) {
|
||||
final QueryParameterImplementor qp = getParameterMetadata().getQueryParameter( name );
|
||||
if ( qp == null ) {
|
||||
throw new IllegalArgumentException( "The parameter [" + name + "] is not part of this Query" );
|
||||
final QueryParameterImplementor<?> parameter = getParameterMetadata().getQueryParameter( name );
|
||||
if ( parameter == null ) {
|
||||
throw new IllegalArgumentException( "Could not resolve parameter by name - " + name );
|
||||
}
|
||||
|
||||
final QueryParameterBinding binding = getQueryParameterBindings().getBinding( qp );
|
||||
final QueryParameterBinding<?> binding = getQueryParameterBindings().getBinding( parameter );
|
||||
if ( binding == null || !binding.isBound() ) {
|
||||
throw new IllegalStateException( "The parameter [" + name + "] has not yet been bound" );
|
||||
throw new IllegalStateException( "Parameter value not yet bound : " + parameter.toString() );
|
||||
}
|
||||
|
||||
if ( binding.isMultiValued() ) {
|
||||
|
@ -1217,12 +1225,12 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public Object getParameterValue(int position) {
|
||||
final QueryParameterImplementor qp = getParameterMetadata().getQueryParameter( position );
|
||||
if ( qp == null ) {
|
||||
throw new IllegalArgumentException( "The parameter [" + position + "] is not part of this Query" );
|
||||
final QueryParameterImplementor<?> parameter = getParameterMetadata().getQueryParameter( position );
|
||||
if ( parameter == null ) {
|
||||
throw new IllegalArgumentException( "Could not resolve parameter by position - " + position );
|
||||
}
|
||||
|
||||
final QueryParameterBinding binding = getQueryParameterBindings().getBinding( qp );
|
||||
final QueryParameterBinding<?> binding = getQueryParameterBindings().getBinding( parameter );
|
||||
if ( binding == null || !binding.isBound() ) {
|
||||
throw new IllegalStateException( "The parameter [" + position + "] has not yet been bound" );
|
||||
}
|
||||
|
@ -1271,7 +1279,7 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
|
||||
@Override
|
||||
public QueryImplementor<R> setProperties(Object bean) {
|
||||
Class clazz = bean.getClass();
|
||||
final Class<?> clazz = bean.getClass();
|
||||
for ( String paramName : getParameterMetadata().getNamedParameterNames() ) {
|
||||
try {
|
||||
final PropertyAccess propertyAccess = BuiltInPropertyAccessStrategies.BASIC.getStrategy().buildPropertyAccess(
|
||||
|
@ -1279,16 +1287,16 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
paramName
|
||||
);
|
||||
final Getter getter = propertyAccess.getGetter();
|
||||
final Class retType = getter.getReturnType();
|
||||
final Class<?> retType = getter.getReturnType();
|
||||
final Object object = getter.get( bean );
|
||||
if ( Collection.class.isAssignableFrom( retType ) ) {
|
||||
setParameterList( paramName, (Collection) object );
|
||||
setParameterList( paramName, (Collection<?>) object );
|
||||
}
|
||||
else if ( retType.isArray() ) {
|
||||
setParameterList( paramName, (Object[]) object );
|
||||
}
|
||||
else {
|
||||
AllowableParameterType type = determineType( paramName, retType );
|
||||
AllowableParameterType<?> type = determineType( paramName, retType );
|
||||
setParameter( paramName, object, type );
|
||||
}
|
||||
}
|
||||
|
@ -1300,8 +1308,8 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected AllowableParameterType determineType(String namedParam, Class retType) {
|
||||
AllowableParameterType type = locateBinding( namedParam ).getBindType();
|
||||
protected AllowableParameterType<?> determineType(String namedParam, Class<?> retType) {
|
||||
AllowableParameterType<?> type = locateBinding( namedParam ).getBindType();
|
||||
if ( type == null ) {
|
||||
type = getParameterMetadata().getQueryParameter( namedParam ).getHibernateType();
|
||||
}
|
||||
|
@ -1312,8 +1320,8 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public QueryImplementor setProperties(Map map) {
|
||||
@SuppressWarnings( "rawtypes" )
|
||||
public QueryImplementor<R> setProperties(Map map) {
|
||||
for ( String paramName : getParameterMetadata().getNamedParameterNames() ) {
|
||||
final Object object = map.get( paramName );
|
||||
if ( object == null ) {
|
||||
|
@ -1417,12 +1425,12 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ScrollableResultsImplementor scroll() {
|
||||
public ScrollableResultsImplementor<?> scroll() {
|
||||
return scroll( getSession().getFactory().getJdbcServices().getJdbcEnvironment().getDialect().defaultScrollMode() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScrollableResultsImplementor scroll(ScrollMode scrollMode) {
|
||||
public ScrollableResultsImplementor<?> scroll(ScrollMode scrollMode) {
|
||||
beforeQuery( false );
|
||||
try {
|
||||
return doScroll( scrollMode );
|
||||
|
@ -1432,10 +1440,10 @@ public abstract class AbstractQuery<R> implements QueryImplementor<R> {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract ScrollableResultsImplementor doScroll(ScrollMode scrollMode);
|
||||
protected abstract ScrollableResultsImplementor<?> doScroll(ScrollMode scrollMode);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings( {"unchecked", "rawtypes"} )
|
||||
public Stream<R> stream() {
|
||||
final ScrollableResultsImplementor scrollableResults = scroll( ScrollMode.FORWARD_ONLY );
|
||||
final ScrollableResultsIterator<R> iterator = new ScrollableResultsIterator<>( scrollableResults );
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.sql;
|
||||
|
||||
import org.hibernate.query.QueryLogging;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NativeQueryLogging {
|
||||
public static final Logger LOGGER = QueryLogging.subLogger( "native" );
|
||||
|
||||
public static final boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
|
||||
public static final boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
|
||||
}
|
|
@ -19,6 +19,8 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
@ -106,6 +108,7 @@ public class NativeQueryImpl<R>
|
|||
private final QueryParameterBindings parameterBindings;
|
||||
|
||||
private final ResultSetMappingImpl resultSetMapping;
|
||||
private final boolean resultMappingSuppliedToCtor;
|
||||
|
||||
private final QueryOptionsImpl queryOptions = new QueryOptionsImpl();
|
||||
|
||||
|
@ -120,56 +123,78 @@ public class NativeQueryImpl<R>
|
|||
public NativeQueryImpl(
|
||||
NamedNativeQueryMemento memento,
|
||||
SharedSessionContractImplementor session) {
|
||||
super( session );
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( memento.getSqlString(), session );
|
||||
|
||||
this.sqlString = parameterInterpretation.getAdjustedSqlString();
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this(
|
||||
memento,
|
||||
() -> {
|
||||
if ( memento.getResultMappingName() != null ) {
|
||||
this.resultSetMapping = new ResultSetMappingImpl( memento.getResultMappingName() );
|
||||
final NamedResultSetMappingMemento resultSetMappingMemento = getSessionFactory().getQueryEngine()
|
||||
.getNamedQueryRepository()
|
||||
.getResultSetMappingMemento( memento.getResultMappingName() );
|
||||
resultSetMappingMemento.resolve(
|
||||
resultSetMapping,
|
||||
this::addSynchronizedQuerySpace,
|
||||
this
|
||||
);
|
||||
return new ResultSetMappingImpl( memento.getResultMappingName() );
|
||||
}
|
||||
else if ( memento.getResultMappingClass() != null ) {
|
||||
this.resultSetMapping = new ResultSetMappingImpl( memento.getResultMappingName() );
|
||||
return new ResultSetMappingImpl( memento.getResultMappingClass().getName() );
|
||||
}
|
||||
|
||||
return new ResultSetMappingImpl( memento.getSqlString() );
|
||||
},
|
||||
(resultSetMapping, querySpaceConsumer, context ) -> {
|
||||
if ( memento.getResultMappingName() != null ) {
|
||||
final NamedResultSetMappingMemento resultSetMappingMemento = session.getFactory()
|
||||
.getQueryEngine()
|
||||
.getNamedQueryRepository()
|
||||
.getResultSetMappingMemento( memento.getResultMappingName() );
|
||||
resultSetMappingMemento.resolve( resultSetMapping, querySpaceConsumer, context );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( memento.getResultMappingClass() != null ) {
|
||||
resultSetMapping.addResultBuilder(
|
||||
Builders.implicitEntityResultBuilder(
|
||||
memento.getResultMappingClass(),
|
||||
this
|
||||
context
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
this.resultSetMapping = new ResultSetMappingImpl( sqlString );
|
||||
return true;
|
||||
}
|
||||
|
||||
applyOptions( memento );
|
||||
return false;
|
||||
},
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
private NativeQueryImpl(
|
||||
String resultMappingIdentifier,
|
||||
@FunctionalInterface
|
||||
private interface ResultSetMappingHandler {
|
||||
boolean resolveResultSetMapping(
|
||||
ResultSetMappingImpl resultSetMapping,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context);
|
||||
}
|
||||
|
||||
public NativeQueryImpl(
|
||||
NamedNativeQueryMemento memento,
|
||||
Supplier<ResultSetMappingImpl> resultSetMappingCreator,
|
||||
ResultSetMappingHandler resultSetMappingHandler,
|
||||
SharedSessionContractImplementor session) {
|
||||
super( session );
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( memento.getSqlString(), session );
|
||||
final String mementoSqlString = memento.getSqlString();
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( mementoSqlString, session );
|
||||
|
||||
this.sqlString = parameterInterpretation.getAdjustedSqlString();
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
this.querySpaces = new HashSet<>();
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultMappingIdentifier );
|
||||
this.resultSetMapping = resultSetMappingCreator.get();
|
||||
|
||||
//noinspection UnnecessaryLocalVariable
|
||||
final boolean appliedAnyResults = resultSetMappingHandler.resolveResultSetMapping(
|
||||
resultSetMapping,
|
||||
querySpaces::add,
|
||||
this
|
||||
);
|
||||
|
||||
this.resultMappingSuppliedToCtor = appliedAnyResults;
|
||||
|
||||
applyOptions( memento );
|
||||
}
|
||||
|
@ -181,12 +206,25 @@ public class NativeQueryImpl<R>
|
|||
NamedNativeQueryMemento memento,
|
||||
Class<R> resultJavaType,
|
||||
SharedSessionContractImplementor session) {
|
||||
this( memento, session );
|
||||
this(
|
||||
memento,
|
||||
() -> new ResultSetMappingImpl( resultJavaType.getName() ),
|
||||
(resultSetMapping, querySpaceConsumer, context) -> {
|
||||
if ( resultJavaType != null ) {
|
||||
|
||||
// todo (6.0) : need to add handling for `javax.persistence.NamedNativeQuery#resultSetMapping`
|
||||
// and `javax.persistence.NamedNativeQuery#resultClass`
|
||||
// todo (6.0) : really `resultJavaType` could be any type nature - basic, embedded, entity
|
||||
|
||||
// todo (6.0) : relatedly, does `resultJavaType` come from `NamedNativeQuery#resultClass`?
|
||||
resultSetMapping.addResultBuilder(
|
||||
Builders.implicitEntityResultBuilder( resultJavaType, context )
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
session
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,13 +234,21 @@ public class NativeQueryImpl<R>
|
|||
NamedNativeQueryMemento memento,
|
||||
String resultSetMappingName,
|
||||
SharedSessionContractImplementor session) {
|
||||
this( resultSetMappingName, memento, session );
|
||||
|
||||
session.getFactory()
|
||||
this(
|
||||
memento,
|
||||
() -> new ResultSetMappingImpl( resultSetMappingName ),
|
||||
(resultSetMapping, querySpaceConsumer, context) -> {
|
||||
final NamedResultSetMappingMemento mappingMemento = session.getFactory()
|
||||
.getQueryEngine()
|
||||
.getNamedQueryRepository()
|
||||
.getResultSetMappingMemento( resultSetMappingName )
|
||||
.resolve( resultSetMapping, this::addSynchronizedQuerySpace, this );
|
||||
.getResultSetMappingMemento( resultSetMappingName );
|
||||
assert mappingMemento != null;
|
||||
mappingMemento.resolve( resultSetMapping, querySpaceConsumer, context );
|
||||
return true;
|
||||
},
|
||||
session
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public NativeQueryImpl(
|
||||
|
@ -211,6 +257,13 @@ public class NativeQueryImpl<R>
|
|||
AbstractSharedSessionContract session) {
|
||||
super( session );
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( sqlString, session );
|
||||
|
||||
this.sqlString = parameterInterpretation.getAdjustedSqlString();
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultSetMappingMemento.getName() );
|
||||
resultSetMappingMemento.resolve(
|
||||
resultSetMapping,
|
||||
|
@ -218,12 +271,7 @@ public class NativeQueryImpl<R>
|
|||
this
|
||||
);
|
||||
|
||||
final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( sqlString, session );
|
||||
|
||||
this.sqlString = parameterInterpretation.getAdjustedSqlString();
|
||||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
this.resultMappingSuppliedToCtor = true;
|
||||
}
|
||||
|
||||
private ParameterInterpretation resolveParameterInterpretation(
|
||||
|
@ -268,6 +316,7 @@ public class NativeQueryImpl<R>
|
|||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( sqlString );
|
||||
this.resultMappingSuppliedToCtor = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -310,20 +359,29 @@ public class NativeQueryImpl<R>
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean canApplyAliasSpecificLockModes() {
|
||||
return false;
|
||||
public LockModeType getLockMode() {
|
||||
throw new IllegalStateException( "Illegal attempt to get lock mode on a native-query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingLockMode() {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a native query" );
|
||||
public NativeQueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
super.setLockOptions( lockOptions );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingAliasSpecificLockModes() {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a native query" );
|
||||
public NativeQueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
super.setLockMode( alias, lockMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockMode(LockModeType lockModeType) {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a native-query" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Query<R> applyGraph(RootGraph graph, GraphSemantic semantic) {
|
||||
throw new HibernateException( "A native SQL query cannot use EntityGraphs" );
|
||||
|
@ -331,14 +389,22 @@ public class NativeQueryImpl<R>
|
|||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setTupleTransformer(TupleTransformer transformer) {
|
||||
//noinspection unchecked
|
||||
return (NativeQueryImplementor) super.setTupleTransformer( transformer );
|
||||
return (NativeQueryImplementor<R>) super.setTupleTransformer( transformer );
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setResultListTransformer(ResultListTransformer transformer) {
|
||||
//noinspection unchecked
|
||||
return (NativeQueryImplementor) super.setResultListTransformer( transformer );
|
||||
return (NativeQueryImplementor<R>) super.setResultListTransformer( transformer );
|
||||
}
|
||||
|
||||
protected Boolean isSelectQuery() {
|
||||
if ( resultMappingSuppliedToCtor
|
||||
|| resultSetMapping.getNumberOfResultBuilders() > 0
|
||||
|| isReadOnly() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -795,23 +861,6 @@ public class NativeQueryImpl<R>
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockOptions(LockOptions lockOptions) {
|
||||
super.setLockOptions( lockOptions );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockMode(String alias, LockMode lockMode) {
|
||||
super.setLockMode( alias, lockMode );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NativeQueryImplementor<R> setLockMode(LockModeType lockModeType) {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a native SQL query" );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T unwrap(Class<T> javaType) {
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
import org.hibernate.query.internal.QueryParameterNamedImpl;
|
||||
import org.hibernate.query.internal.QueryParameterPositionalImpl;
|
||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||
|
|
|
@ -44,6 +44,16 @@ import org.hibernate.query.spi.QueryImplementor;
|
|||
public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQuery<R>, NameableQuery {
|
||||
NativeQueryImplementor setCollectionKey(Object key);
|
||||
|
||||
@Override
|
||||
default LockOptions getLockOptions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
default LockModeType getLockMode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// covariant overrides - NativeQuery
|
||||
|
||||
|
|
|
@ -6,13 +6,15 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Represents a general uncaught problem performing the interpretation. This might indicate
|
||||
* a semantic (user sqm) problem or a bug in the parser.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class InterpretationException extends RuntimeException {
|
||||
public class InterpretationException extends HibernateException {
|
||||
public InterpretationException(String query) {
|
||||
this( query, null );
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.query.SemanticException;
|
||||
|
||||
/**
|
||||
|
@ -14,7 +15,7 @@ import org.hibernate.query.SemanticException;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ParsingException extends RuntimeException {
|
||||
public class ParsingException extends HibernateException {
|
||||
public ParsingException(String message) {
|
||||
super( message );
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.Tuple;
|
||||
|
@ -39,6 +40,7 @@ import org.hibernate.query.spi.HqlInterpretation;
|
|||
import org.hibernate.query.spi.MutableQueryOptions;
|
||||
import org.hibernate.query.spi.NonSelectQueryPlan;
|
||||
import org.hibernate.query.spi.ParameterMetadataImplementor;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.query.spi.QueryInterpretationCache;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
|
@ -52,7 +54,6 @@ import org.hibernate.query.sqm.tree.SqmStatement;
|
|||
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
|
||||
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
||||
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
|
@ -300,7 +301,7 @@ public class QuerySqmImpl<R>
|
|||
return parameterBindings;
|
||||
}
|
||||
|
||||
private boolean isSelect() {
|
||||
protected Boolean isSelectQuery() {
|
||||
return sqmStatement instanceof SqmSelectStatement;
|
||||
}
|
||||
|
||||
|
@ -314,7 +315,7 @@ public class QuerySqmImpl<R>
|
|||
}
|
||||
|
||||
@Override
|
||||
public Query<R> applyGraph(RootGraph graph, GraphSemantic semantic) {
|
||||
public HqlQueryImplementor<R> applyGraph(RootGraph graph, GraphSemantic semantic) {
|
||||
queryOptions.applyGraph( (RootGraphImplementor<?>) graph, semantic );
|
||||
return this;
|
||||
}
|
||||
|
@ -359,21 +360,23 @@ public class QuerySqmImpl<R>
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean canApplyAliasSpecificLockModes() {
|
||||
return isSelect();
|
||||
public LockModeType getLockMode() {
|
||||
if ( ! isSelectQuery() ) {
|
||||
throw new IllegalStateException( "Illegal attempt to access lock-mode for non-select query" );
|
||||
}
|
||||
|
||||
return super.getLockMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingLockMode() {
|
||||
if ( !isSelect() ) {
|
||||
throw new IllegalStateException( "Illegal attempt to set lock mode on a non-SELECT query" );
|
||||
public HqlQueryImplementor<R> setLockMode(LockModeType lockModeType) {
|
||||
if ( ! LockModeType.NONE.equals( lockModeType ) ) {
|
||||
if ( ! isSelectQuery() ) {
|
||||
throw new IllegalStateException( "Illegal attempt to access lock-mode for non-select query" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void verifySettingAliasSpecificLockModes() {
|
||||
// todo : add a specific Dialect check as well? - if not supported, maybe that can trigger follow-on locks?
|
||||
verifySettingLockMode();
|
||||
return (HqlQueryImplementor<R>) super.setLockMode( lockModeType );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,13 +19,14 @@ public class SqmCreationProcessingStateImpl implements SqmCreationProcessingStat
|
|||
private final SqmCreationState creationState;
|
||||
private final SqmQuery<?> processingQuery;
|
||||
|
||||
private final SqmPathRegistryImpl processingIndex = new SqmPathRegistryImpl( this );
|
||||
private final SqmPathRegistryImpl processingIndex;
|
||||
|
||||
public SqmCreationProcessingStateImpl(
|
||||
SqmQuery<?> processingQuery,
|
||||
SqmCreationState creationState) {
|
||||
this.processingQuery = processingQuery;
|
||||
this.creationState = creationState;
|
||||
this.processingIndex = new SqmPathRegistryImpl( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,10 +22,12 @@ import org.hibernate.NotYetImplementedFor6Exception;
|
|||
import org.hibernate.dialect.function.TimestampaddFunction;
|
||||
import org.hibernate.dialect.function.TimestampdiffFunction;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
|
@ -39,9 +41,9 @@ import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.TemporalUnit;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.UnaryArithmeticOperator;
|
||||
import org.hibernate.query.internal.QueryHelper;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
@ -59,6 +61,7 @@ import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation;
|
|||
import org.hibernate.query.sqm.sql.internal.EmbeddableValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.EntityValuedPathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.PluralValuedSimplePathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstQuerySpecProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
||||
|
@ -112,6 +115,7 @@ import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
|
|||
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmExistsPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
|
||||
|
@ -156,6 +160,7 @@ import org.hibernate.sql.ast.tree.expression.Every;
|
|||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.ExtractUnit;
|
||||
import org.hibernate.sql.ast.tree.expression.Format;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||
import org.hibernate.sql.ast.tree.expression.Star;
|
||||
|
@ -186,11 +191,12 @@ import org.hibernate.sql.exec.spi.JdbcParameters;
|
|||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.internal.util.NullnessHelper.coalesce;
|
||||
import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues;
|
||||
import static org.hibernate.query.BinaryArithmeticOperator.MULTIPLY;
|
||||
import static org.hibernate.query.BinaryArithmeticOperator.SUBTRACT;
|
||||
|
@ -217,6 +223,8 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
}
|
||||
|
||||
private final SqlAstCreationContext creationContext;
|
||||
private final SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private final QueryOptions queryOptions;
|
||||
private final LoadQueryInfluencers loadQueryInfluencers;
|
||||
|
||||
|
@ -247,7 +255,10 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
DomainParameterXref domainParameterXref,
|
||||
QueryParameterBindings domainParameterBindings) {
|
||||
super( creationContext.getServiceRegistry() );
|
||||
|
||||
this.creationContext = creationContext;
|
||||
this.sessionFactory = creationContext.getSessionFactory();
|
||||
|
||||
this.queryOptions = queryOptions;
|
||||
this.loadQueryInfluencers = loadQueryInfluencers;
|
||||
this.domainParameterXref = domainParameterXref;
|
||||
|
@ -2288,6 +2299,68 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
return new ComparisonPredicate( lhs, predicate.getSqmOperator(), rhs );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitIsEmptyPredicate(SqmEmptinessPredicate predicate) {
|
||||
final QuerySpec subQuerySpec = new QuerySpec( false, 1 );
|
||||
|
||||
final SqlAstProcessingState parentState = getProcessingStateStack().getCurrent();
|
||||
|
||||
final SqlAstProcessingStateImpl subQueryState = new SqlAstProcessingStateImpl(
|
||||
parentState,
|
||||
this,
|
||||
currentClauseStack::getCurrent
|
||||
);
|
||||
|
||||
getProcessingStateStack().push( subQueryState );
|
||||
|
||||
final SqmPluralValuedSimplePath<?> sqmPluralPath = predicate.getPluralPath();
|
||||
|
||||
final NavigablePath pluralPathNavPath = sqmPluralPath.getNavigablePath();
|
||||
final NavigablePath parentNavPath = pluralPathNavPath.getParent();
|
||||
assert parentNavPath != null;
|
||||
|
||||
final TableGroup parentTableGroup = parentState
|
||||
.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( parentNavPath );
|
||||
|
||||
subQueryState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup( parentNavPath, parentTableGroup );
|
||||
|
||||
final SqmPathInterpretation<?> sqmPathInterpretation = visitPluralValuedPath( sqmPluralPath );
|
||||
|
||||
|
||||
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) sqmPathInterpretation.getExpressionType();
|
||||
|
||||
// note : do not add to `parentTableGroup` as a join
|
||||
|
||||
final TableGroupJoin tableGroupJoin = pluralAttributeMapping.createTableGroupJoin(
|
||||
pluralPathNavPath,
|
||||
parentTableGroup,
|
||||
sqmPluralPath.getExplicitAlias(),
|
||||
SqlAstJoinType.LEFT,
|
||||
LockMode.NONE,
|
||||
sqlAliasBaseManager,
|
||||
subQueryState,
|
||||
creationContext
|
||||
);
|
||||
|
||||
final TableGroup collectionTableGroup = tableGroupJoin.getJoinedGroup();
|
||||
|
||||
subQuerySpec.getFromClause().addRoot( collectionTableGroup );
|
||||
subQuerySpec.applyPredicate( tableGroupJoin.getPredicate() );
|
||||
|
||||
final ForeignKeyDescriptor collectionKeyDescriptor = pluralAttributeMapping.getKeyDescriptor();
|
||||
final int jdbcTypeCount = collectionKeyDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
|
||||
assert jdbcTypeCount > 0;
|
||||
|
||||
final JdbcLiteral<Integer> jdbcLiteral = new JdbcLiteral<>( 1, StandardBasicTypes.INTEGER );
|
||||
subQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(1,0, jdbcLiteral )
|
||||
);
|
||||
|
||||
return new ExistsPredicate( subQuerySpec );
|
||||
}
|
||||
|
||||
@Override
|
||||
public BetweenPredicate visitBetweenPredicate(SqmBetweenPredicate predicate) {
|
||||
final Expression expression;
|
||||
|
|
|
@ -18,6 +18,7 @@ import javax.persistence.metamodel.MapAttribute;
|
|||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
|
||||
|
@ -154,7 +155,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
|||
@SuppressWarnings("unchecked")
|
||||
public SqmExpression<Class<? extends T>> type() {
|
||||
if ( pathTypeExpression == null ) {
|
||||
final String discriminatorPathName = "{type}";
|
||||
final String discriminatorPathName = EntityDiscriminatorMapping.ROLE_NAME;
|
||||
final NavigablePath discriminatorNavigablePath = getNavigablePath().append( discriminatorPathName );
|
||||
|
||||
final DomainType sqmNodeType = getReferencedPathSource().getSqmPathType();
|
||||
|
|
|
@ -8,23 +8,23 @@ package org.hibernate.query.sqm.tree.predicate;
|
|||
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmEmptinessPredicate extends AbstractNegatableSqmPredicate {
|
||||
private final SqmPath<?> pluralPath;
|
||||
private final SqmPluralValuedSimplePath<?> pluralPath;
|
||||
|
||||
public SqmEmptinessPredicate(
|
||||
SqmPath pluralPath,
|
||||
SqmPluralValuedSimplePath pluralPath,
|
||||
boolean negated,
|
||||
NodeBuilder nodeBuilder) {
|
||||
super( negated, nodeBuilder );
|
||||
this.pluralPath = pluralPath;
|
||||
}
|
||||
|
||||
public SqmPath<?> getPluralPath() {
|
||||
public SqmPluralValuedSimplePath<?> getPluralPath() {
|
||||
return pluralPath;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.sql.ast.spi;
|
||||
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SqlExpressionAccess {
|
||||
Expression getSqlExpression();
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.internal;
|
|||
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||
import org.hibernate.metamodel.mapping.SqlExpressable;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
|
@ -34,7 +35,7 @@ import java.util.Objects;
|
|||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqlSelectionImpl implements SqlSelection {
|
||||
public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
||||
private final int jdbcPosition;
|
||||
private final int valuesArrayPosition;
|
||||
private final Expression sqlExpression;
|
||||
|
@ -94,4 +95,9 @@ public class SqlSelectionImpl implements SqlSelection {
|
|||
public int hashCode() {
|
||||
return Objects.hash( jdbcPosition, valuesArrayPosition, sqlExpression );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression getSqlExpression() {
|
||||
return sqlExpression;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.jpa.test.metamodel.Order_;
|
|||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Similar to {@link org.hibernate.test.jpa.ql.OnKeywordTest}, but here testing from JPA criteria queries.
|
||||
* Similar to {@link org.hibernate.orm.test.query.hql.OnKeywordTest}, but here testing from JPA criteria queries.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.boot.spi.BootstrapContext;
|
|||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.jpa.JpaComplianceStub;
|
||||
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
|
||||
import org.hibernate.metamodel.model.domain.JpaMetamodel;
|
||||
import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl;
|
||||
|
@ -60,7 +61,7 @@ public class HqlTranslationNoFactoryTests {
|
|||
final MetadataImplementor bootModel = modelScope.getDomainModel();
|
||||
final TypeConfiguration typeConfiguration = bootModel.getTypeConfiguration();
|
||||
|
||||
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration );
|
||||
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, new JpaComplianceStub() );
|
||||
|
||||
// todo (6.0) (quarkus) : we should limit the type of the last argument here from `RuntimeModelCreationContext`
|
||||
// which assumes access to SessionFactory
|
||||
|
|
|
@ -9,4 +9,4 @@
|
|||
* Test package for investigating JPA TCK failures - to reproduce them
|
||||
* and, if caused by a Hibernate bug, make sure it does not regress later
|
||||
*/
|
||||
package org.hibernate.test.jpa.compliance;
|
||||
package org.hibernate.orm.test.jpa.compliance;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.RollbackException;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.Parameter;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.LockModeType;
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -39,7 +39,9 @@ public class QueryExecutionTest extends BaseNonConfigCoreFunctionalTestCase {
|
|||
inTransaction(
|
||||
session -> {
|
||||
final List nonDistinctResult = session.createQuery( "select c from Customer c join fetch c.orders" ).list();
|
||||
assertThat( nonDistinctResult.size(), CoreMatchers.is( 2 ) );
|
||||
// note: this was historically `2` because Hibernate would return a root result for each of its fetched rows.
|
||||
// - that was confusing behavior for users. we have changed this in 6 to be more logical
|
||||
assertThat( nonDistinctResult.size(), CoreMatchers.is( 1 ) );
|
||||
|
||||
final List distinctResult = session.createQuery( "select distinct c from Customer c join fetch c.orders" ).list();
|
||||
assertThat( distinctResult.size(), CoreMatchers.is( 1 ) );
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.Entity;
|
||||
|
@ -20,6 +20,7 @@ import org.hibernate.dialect.H2Dialect;
|
|||
import org.hibernate.procedure.ProcedureCall;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.hibernate.test.sql.storedproc.StoredProcedureResultSetMappingTest;
|
||||
|
@ -31,6 +32,7 @@ import static org.junit.Assert.fail;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@RequiresDialect( H2Dialect.class )
|
||||
@FailureExpected( message = "Procedure/function support not yet implemented", jiraKey = "n/a" )
|
||||
public class StoredProcedureApiTests extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.caching;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.caching;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.caching;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.caching;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.persistence.Cacheable;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.caching;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.caching;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.persistence.Cacheable;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.joincolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.joincolumn;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.joincolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.joincolumn;
|
||||
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.joincolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.joincolumn;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2.mapkeycolumn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -10,4 +10,4 @@
|
|||
*
|
||||
* @see org.hibernate.test.jpa.compliance
|
||||
*/
|
||||
package org.hibernate.test.jpa.compliance.tck2_2;
|
||||
package org.hibernate.orm.test.jpa.compliance.tck2_2;
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* 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>.
|
||||
* 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.test.jpa.ql;
|
||||
package org.hibernate.orm.test.query.hql;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* 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>.
|
||||
* 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.test.jpa.ql;
|
||||
package org.hibernate.orm.test.query.hql;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -10,10 +10,17 @@ import java.time.Instant;
|
|||
import java.time.temporal.ChronoUnit;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.event.service.spi.EventListenerRegistry;
|
||||
import org.hibernate.event.spi.EventType;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -35,6 +42,13 @@ public class NativeQueryParameterTests {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaStylePositionalParametersInNativeSql(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
s -> s.createNativeQuery( "select t.subject from ticket t where t.key = ?1" ).setParameter( 1, "ABC-123" ).list()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypedParameterBinding(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
|
|
|
@ -45,9 +45,9 @@ public class JPAQLComplianceTest extends AbstractJPATest {
|
|||
Session s = openSession( );
|
||||
// a control test (a user reported that the JPA 'case insensitivity' support
|
||||
// caused problems with the "discriminator resolution" code; unable to reproduce)...
|
||||
s.createQuery( "from MyEntity e where e.class = MySubclassEntity" );
|
||||
s.createQuery( "from MyEntity e where e.other.class = MySubclassEntity" );
|
||||
s.createQuery( "from MyEntity where other.class = MySubclassEntity" );
|
||||
s.createQuery( "select E from MyEntity e where other.class = MySubclassEntity" );
|
||||
s.createQuery( "select e from MyEntity e where e.other.class = MySubclassEntity" );
|
||||
s.createQuery( "select e from MyEntity E where e.class = MySubclassEntity" );
|
||||
|
||||
s.createQuery( "select object(I) from Item i").list();
|
||||
s.close();
|
||||
|
|
|
@ -1,22 +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.test.jpa.ql;
|
||||
|
||||
import org.hibernate.test.jpa.AbstractJPATest;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NativeQueryTest extends AbstractJPATest {
|
||||
@Test
|
||||
public void testJpaStylePositionalParametersInNativeSql() {
|
||||
inTransaction(
|
||||
s -> s.createNativeQuery( "select NAME from EJB3_ITEM where ITEM_ID = ?1" ).setParameter( 1, 123L ).list()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
|||
log4j.appender.stdout2=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout2.Target=System.out
|
||||
log4j.appender.stdout2.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout2.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{5}:%L - %m%n
|
||||
log4j.appender.stdout2.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{5}:(%C{1}:%L) - %m%n
|
||||
|
||||
log4j.appender.unclosedSessionFactoryFile=org.apache.log4j.FileAppender
|
||||
log4j.appender.unclosedSessionFactoryFile.append=true
|
||||
|
@ -29,7 +29,7 @@ log4j.logger.org.hibernate.orm.sql.results=debug
|
|||
|
||||
log4j.logger.org.hibernate.orm.graph=debug
|
||||
log4j.logger.org.hibernate.orm.query.sqm=debug
|
||||
log4j.logger.org.hibernate.orm.query.hql=debug
|
||||
log4j.logger.org.hibernate.orm.query.hql=trace
|
||||
log4j.logger.org.hibernate.sql.results.graph.DomainResultGraphPrinter=debug
|
||||
|
||||
log4j.logger.org.hibernate.tool.hbm2ddl=trace
|
||||
|
|
Loading…
Reference in New Issue