diff --git a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEmbeddableTuplizer.java b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEmbeddableTuplizer.java index 932021beb6..326b099d5d 100644 --- a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEmbeddableTuplizer.java +++ b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEmbeddableTuplizer.java @@ -8,7 +8,7 @@ //$Id$ package org.hibernate.userguide.proxy.tuplizer; import org.hibernate.mapping.Component; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.component.PojoComponentTuplizer; /** diff --git a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEntityTuplizer.java b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEntityTuplizer.java index cbb364986d..647782e276 100644 --- a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEntityTuplizer.java +++ b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicEntityTuplizer.java @@ -10,7 +10,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.ProxyFactory; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.PojoEntityTuplizer; diff --git a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicInstantiator.java b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicInstantiator.java index 820c6305b8..c735d3755f 100644 --- a/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicInstantiator.java +++ b/documentation/src/test/java/org/hibernate/userguide/proxy/tuplizer/DynamicInstantiator.java @@ -11,7 +11,7 @@ package org.hibernate.userguide.proxy.tuplizer; import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; /** * @author Emmanuel Bernard diff --git a/hibernate-core/src/main/java/org/hibernate/Session.java b/hibernate-core/src/main/java/org/hibernate/Session.java index 6b9c39db05..18c160d241 100644 --- a/hibernate-core/src/main/java/org/hibernate/Session.java +++ b/hibernate-core/src/main/java/org/hibernate/Session.java @@ -21,7 +21,6 @@ import org.hibernate.graph.RootGraph; import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.Work; import org.hibernate.jpa.HibernateEntityManager; -import org.hibernate.query.NativeQuery; import org.hibernate.stat.SessionStatistics; /** @@ -677,21 +676,6 @@ public interface Session extends SharedSessionContract, EntityManager, Hibernate */ LockMode getCurrentLockMode(Object object); - /** - * Create a {@link Query} instance for the given collection and filter string. Contains an implicit {@code FROM} - * element named {@code this} which refers to the defined table for the collection elements, as well as an implicit - * {@code WHERE} restriction for this particular collection instance's key value. - * - * @param collection a persistent collection - * @param queryString a Hibernate query fragment. - * - * @return The query instance for manipulation and execution - * - * @deprecated (since 5.3) with no real replacement. - */ - @Deprecated - org.hibernate.Query createFilter(Object collection, String queryString); - /** * Completely clear the session. Evict all loaded instances and cancel all pending * saves, updates and deletions. Do not close open iterators or instances of @@ -1178,7 +1162,4 @@ public interface Session extends SharedSessionContract, EntityManager, Hibernate org.hibernate.query.Query createNamedQuery(String name, Class resultType); - - @Override - NativeQuery createSQLQuery(String queryString); } diff --git a/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java index e5e49f95ea..1285333e7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java @@ -114,57 +114,6 @@ public interface SharedSessionContract extends QueryProducer, Serializable { */ ProcedureCall createStoredProcedureCall(String procedureName, String... resultSetMappings); - /** - * Create {@link Criteria} instance for the given class (entity or subclasses/implementors). - * - * @param persistentClass The class, which is an entity, or has entity subclasses/implementors - * - * @return The criteria instance for manipulation and execution - * - * @deprecated (since 5.2) for Session, use the JPA Criteria - */ - @Deprecated - Criteria createCriteria(Class persistentClass); - - /** - * Create {@link Criteria} instance for the given class (entity or subclasses/implementors), using a specific - * alias. - * - * @param persistentClass The class, which is an entity, or has entity subclasses/implementors - * @param alias The alias to use - * - * @return The criteria instance for manipulation and execution - * - * @deprecated (since 5.2) for Session, use the JPA Criteria - */ - @Deprecated - Criteria createCriteria(Class persistentClass, String alias); - - /** - * Create {@link Criteria} instance for the given entity name. - * - * @param entityName The entity name - - * @return The criteria instance for manipulation and execution - * - * @deprecated (since 5.2) for Session, use the JPA Criteria - */ - @Deprecated - Criteria createCriteria(String entityName); - - /** - * Create {@link Criteria} instance for the given entity name, using a specific alias. - * - * @param entityName The entity name - * @param alias The alias to use - * - * @return The criteria instance for manipulation and execution - * - * @deprecated (since 5.2) for Session, use the JPA Criteria - */ - @Deprecated - Criteria createCriteria(String entityName, String alias); - /** * Get the Session-level JDBC batch size for the current Session. * Overrides the SessionFactory JDBC batch size defined by the {@code hibernate.default_batch_fetch_size} configuration property for the scope of the current {@code Session}. diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java index 3b40ef4711..5e52c84a0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/QueryHints.java @@ -6,7 +6,6 @@ */ package org.hibernate.annotations; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.graph.GraphSemantic; /** diff --git a/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java index faa2398b06..1326eb6dfc 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java @@ -752,6 +752,20 @@ public interface SessionFactoryBuilder { */ SessionFactoryBuilder enableJpaClosedCompliance(boolean enabled); + /** + * See the discussion on {@link org.hibernate.cfg.AvailableSettings#NATIVE_QUERY_ORDINAL_PARAMETER_BASE} + *

+ * The passed value will be validated to be either:

    + *
  • 0
  • + *
  • 1
  • + *
  • {@code null}
  • + *
+ * + * @param base The base to use. + * + * @return {@code this}, for method chaining + */ + SessionFactoryBuilder applyNonJpaNativeQueryOrdinalParameterBase(Integer base); /** * Allows unwrapping this builder as another, more specific type. diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java index 626cc6450c..32d9ea6c83 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java @@ -27,7 +27,6 @@ import org.hibernate.cfg.BaselineSessionEventsListenerBuilder; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy; import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.loader.BatchFetchStyle; import org.hibernate.proxy.EntityNotFoundDelegate; @@ -318,6 +317,42 @@ public interface SessionFactoryOptions { SqmFunctionRegistry getSqmFunctionRegistry(); + /** + * See {@link org.hibernate.cfg.AvailableSettings#NATIVE_QUERY_ORDINAL_PARAMETER_BASE} and + * {@link org.hibernate.boot.SessionFactoryBuilder#applyNonJpaNativeQueryOrdinalParameterBase(Integer)} for details. + * + * @return The base integer for ordinal parameters + * + * @since 6.0 + */ + Integer getNonJpaNativeQueryOrdinalParameterBase(); + + /** + * Controls whether Hibernate should try to map named parameter names + * specified in a {@link org.hibernate.procedure.ProcedureCall} or + * {@link javax.persistence.StoredProcedureQuery} to named parameters in + * the JDBC {@link java.sql.CallableStatement}. + *

+ * As JPA is defined, the use of named parameters is essentially of dubious + * value since by spec the parameters have to be defined in the order they are + * defined in the procedure/function declaration - we can always bind them + * positionally. The whole idea of named parameters for CallableStatement + * is the ability to bind these in any order, but since we unequivocally + * know the order anyway binding them via name really gains nothing. + *

+ * If this is {@code true}, we still need to make sure the Dialect supports + * named binding. Setting this to {@code false} simply circumvents that + * check and always performs positional binding. + * + * @return {@code true} indicates we should try to use {@link java.sql.CallableStatement} + * named parameters, if the Dialect says it is supported; {@code false} + * indicates that we should never try to use {@link java.sql.CallableStatement} + * named parameters, regardless of what the Dialect says. + * + * @see org.hibernate.cfg.AvailableSettings#CALLABLE_NAMED_PARAMS_ENABLED + */ + boolean isUseOfJdbcNamedParametersEnabled(); + boolean isOmitJoinOfSuperclassTablesEnabled(); } diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java index 6bc6c427df..8e431ce822 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/QueryKey.java @@ -13,7 +13,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 67e1537d60..a6aba7d1d7 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -13,6 +13,7 @@ import org.hibernate.HibernateException; import org.hibernate.Transaction; import org.hibernate.boot.MetadataBuilder; import org.hibernate.boot.registry.classloading.internal.TcclLookupPrecedence; +import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.cache.spi.TimestampsCacheFactory; import org.hibernate.internal.log.DeprecationLogger; import org.hibernate.jpa.spi.JpaCompliance; @@ -868,6 +869,46 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings { */ String ENFORCE_LEGACY_PROXY_CLASSNAMES = "hibernate.bytecode.enforce_legacy_proxy_classnames"; + + /** + * Controls the base integer for binding JDBC-style ({@code ?}) ordinal + * parameters when the Hibernate SessionFactory is bootstrapped via the native + * bootstrapping API. JPA says that all non-named parameter binding is explicitly + * 1-based; so when bootstrapped via JPA, Hibernate always treats these as 1-based. + *

+ * Note that this affects only ordinal parameters. Positional + * parameters (e.g. {@code ?1}) explicitly define the binding position (1) in + * their declaration, whereas the binding position is implicit with ordinal + * parameters based on its ordinal position in the query. As of 6.0, support + * for this ordinal parameter declaration form has been removed from HQL and + * is now only valid for {@link org.hibernate.query.NativeQuery}s. + *

+ * Historically Hibernate followed JDBC conventions for ordinal parameter binding + * such that the implied positions were 0-based. This presents a mismatch between + * how to bind ordinal parameters based on how the SessionFactory was bootstrapped, + * which is not ideal. This setting then seeks to allow unifying how these are + * handled regardless of the bootstrap method. The expected value of this setting + * is an integer value of either 0 (the default) or 1. The default follows the legacy + * expectations and allows legacy Hibernate apps to continue to work. Setting this + * to 1 (one) allows all non-named parameter binding to be unified as 1-based. + * + * @since 6.0 + */ + String NATIVE_QUERY_ORDINAL_PARAMETER_BASE = "hibernate.query.native.ordinal_parameter_base"; + + /** + * Global setting name for controlling whether Hibernate should try to map + * named parameter names specified in a + * {@link org.hibernate.procedure.ProcedureCall} or + * {@link javax.persistence.StoredProcedureQuery} to named parameters in + * the JDBC {@link java.sql.CallableStatement}. + * + * @see SessionFactoryOptions#isUseOfJdbcNamedParametersEnabled() + * + * @since 6.0 + */ + String CALLABLE_NAMED_PARAMS_ENABLED = "hibernate.query.proc.callable_named_params_enabled"; + /** * Should Hibernate use enhanced entities "as a proxy"? * diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java deleted file mode 100644 index e4ba252531..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java +++ /dev/null @@ -1,99 +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 . - */ -package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.QueryException; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.persister.collection.QueryableCollection; -import org.hibernate.persister.entity.Loadable; -import org.hibernate.persister.entity.PropertyMapping; -import org.hibernate.sql.ConditionFragment; -import org.hibernate.type.CollectionType; -import org.hibernate.type.Type; - -/** - * Base expression implementation for (not) emptiness checking of collection properties - * - * @author Steve Ebersole - */ -public abstract class AbstractEmptinessExpression implements Criterion { - - private static final TypedValue[] NO_VALUES = new TypedValue[0]; - - protected final String propertyName; - - protected AbstractEmptinessExpression(String propertyName) { - this.propertyName = propertyName; - } - - /** - * Should empty rows be excluded? - * - * @return {@code true} Indicates the expression should be 'exists'; {@code false} indicates 'not exists' - */ - protected abstract boolean excludeEmpty(); - - @Override - public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String entityName = criteriaQuery.getEntityName( criteria, propertyName ); - final String actualPropertyName = criteriaQuery.getPropertyName( propertyName ); - final String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName ); - - final SessionFactoryImplementor factory = criteriaQuery.getFactory(); - final QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory ); - - final String[] collectionKeys = collectionPersister.getKeyColumnNames(); - final String[] ownerKeys = ( (Loadable) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames(); - - final String innerSelect = "(select 1 from " + collectionPersister.getTableName() + " where " - + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString() - + ")"; - - return excludeEmpty() - ? "exists " + innerSelect - : "not exists " + innerSelect; - } - - - protected QueryableCollection getQueryableCollection( - String entityName, - String propertyName, - SessionFactoryImplementor factory) throws HibernateException { - final PropertyMapping ownerMapping = (PropertyMapping) factory.getEntityPersister( entityName ); - final Type type = ownerMapping.toType( propertyName ); - if ( !type.isCollectionType() ) { - throw new MappingException( - "Property path [" + entityName + "." + propertyName + "] does not reference a collection" - ); - } - - final String role = ( (CollectionType) type ).getRole(); - try { - return (QueryableCollection) factory.getCollectionPersister( role ); - } - catch ( ClassCastException cce ) { - throw new QueryException( "collection role is not queryable: " + role ); - } - catch ( Exception e ) { - throw new QueryException( "collection role not found: " + role ); - } - } - - @Override - public final TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException { - return NO_VALUES; - } - - @Override - public final String toString() { - return propertyName + ( excludeEmpty() ? " is not empty" : " is empty" ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/AggregateProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/AggregateProjection.java deleted file mode 100644 index 4b7c8bfbea..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/AggregateProjection.java +++ /dev/null @@ -1,85 +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 . - */ -package org.hibernate.criterion; -import java.util.Collections; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.type.Type; - -/** - * Base class for standard aggregation functions. - * - * @author max - */ -public class AggregateProjection extends SimpleProjection { - protected final String propertyName; - private final String functionName; - - protected AggregateProjection(String functionName, String propertyName) { - this.functionName = functionName; - this.propertyName = propertyName; - } - - public String getFunctionName() { - return functionName; - } - - public String getPropertyName() { - return propertyName; - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new Type[] { - getFunction( criteriaQuery ).getReturnType( - criteriaQuery.getType( criteria, getPropertyName() ), - criteriaQuery.getFactory() - ) - }; - } - - @Override - public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException { - final String functionFragment = getFunction( criteriaQuery ).render( - criteriaQuery.getType( criteria, getPropertyName() ), - buildFunctionParameterList( criteria, criteriaQuery ), - criteriaQuery.getFactory() - ); - return functionFragment + " as y" + loc + '_'; - } - - protected SQLFunction getFunction(CriteriaQuery criteriaQuery) { - return getFunction( getFunctionName(), criteriaQuery ); - } - - protected SQLFunction getFunction(String functionName, CriteriaQuery criteriaQuery) { - final SQLFunction function = criteriaQuery.getFactory() - .getSqlFunctionRegistry() - .findSQLFunction( functionName ); - if ( function == null ) { - throw new HibernateException( "Unable to locate mapping for function named [" + functionName + "]" ); - } - return function; - } - - protected List buildFunctionParameterList(Criteria criteria, CriteriaQuery criteriaQuery) { - return buildFunctionParameterList( criteriaQuery.getColumn( criteria, getPropertyName() ) ); - } - - protected List buildFunctionParameterList(String column) { - return Collections.singletonList( column ); - } - - @Override - public String toString() { - return functionName + "(" + propertyName + ')'; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/AliasedProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/AliasedProjection.java deleted file mode 100755 index 220a45f637..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/AliasedProjection.java +++ /dev/null @@ -1,89 +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 . - */ -package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.type.Type; - -/** - * Represents a projection that specifies an alias - * - * @author Gavin King - */ -public class AliasedProjection implements EnhancedProjection { - private final Projection projection; - private final String alias; - - protected AliasedProjection(Projection projection, String alias) { - this.projection = projection; - this.alias = alias; - } - - @Override - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { - return projection.toSqlString( criteria, position, criteriaQuery ); - } - - @Override - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return projection.toGroupSqlString( criteria, criteriaQuery ); - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return projection.getTypes( criteria, criteriaQuery ); - } - - @Override - public String[] getColumnAliases(int loc) { - return projection.getColumnAliases( loc ); - } - - @Override - public String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - return projection instanceof EnhancedProjection - ? ( (EnhancedProjection) projection ).getColumnAliases( loc, criteria, criteriaQuery ) - : getColumnAliases( loc ); - } - - @Override - public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return this.alias.equals( alias ) - ? getTypes( criteria, criteriaQuery ) - : null; - } - - @Override - public String[] getColumnAliases(String alias, int loc) { - return this.alias.equals( alias ) - ? getColumnAliases( loc ) - : null; - } - - @Override - public String[] getColumnAliases(String alias, int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - return this.alias.equals( alias ) - ? getColumnAliases( loc, criteria, criteriaQuery ) - : null; - } - - @Override - public String[] getAliases() { - return new String[] { alias }; - } - - @Override - public boolean isGrouped() { - return projection.isGrouped(); - } - - @Override - public String toString() { - return projection.toString() + " as " + alias; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/AvgProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/AvgProjection.java deleted file mode 100755 index 17093ab2d1..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/AvgProjection.java +++ /dev/null @@ -1,23 +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 . - */ -package org.hibernate.criterion; - -/** - * An avg() projection - * - * @author Gavin King - */ -public class AvgProjection extends AggregateProjection { - /** - * Constructs the AvgProjection - * - * @param propertyName The name of the property to average - */ - public AvgProjection(String propertyName) { - super( "avg", propertyName ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/BetweenExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/BetweenExpression.java deleted file mode 100644 index cd295af32e..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/BetweenExpression.java +++ /dev/null @@ -1,50 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * Constrains a property to between two values - * - * @author Gavin King - */ -public class BetweenExpression implements Criterion { - private final String propertyName; - private final Object low; - private final Object high; - - protected BetweenExpression(String propertyName, Object low, Object high) { - this.propertyName = propertyName; - this.low = low; - this.high = high; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - final String[] expressions = StringHelper.suffix( columns, " between ? and ?" ); - return String.join( " and ", expressions ); - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new TypedValue[] { - criteriaQuery.getTypedValue( criteria, propertyName, low), - criteriaQuery.getTypedValue( criteria, propertyName, high) - }; - } - - @Override - public String toString() { - return propertyName + " between " + low + " and " + high; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Conjunction.java b/hibernate-core/src/main/java/org/hibernate/criterion/Conjunction.java deleted file mode 100644 index 5f95bdcea9..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Conjunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.criterion; - -/** - * Defines a conjunction (AND series). - * - * @author Gavin King - * @author Steve Ebersole - * - * @see Disjunction - */ -public class Conjunction extends Junction { - /** - * Constructs a Conjunction - */ - public Conjunction() { - super( Nature.AND ); - } - - protected Conjunction(Criterion... criterion) { - super( Nature.AND, criterion ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/CountProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/CountProjection.java deleted file mode 100755 index 50fee4b5c4..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/CountProjection.java +++ /dev/null @@ -1,68 +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 . - */ -package org.hibernate.criterion; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.hibernate.Criteria; - -/** - * A count projection - * - * @author Gavin King - */ -public class CountProjection extends AggregateProjection { - private boolean distinct; - - /** - * Constructs the count projection. - * - * @param prop The property name - * - * @see Projections#count(String) - * @see Projections#countDistinct(String) - */ - protected CountProjection(String prop) { - super( "count", prop ); - } - - @Override - protected List buildFunctionParameterList(Criteria criteria, CriteriaQuery criteriaQuery) { - final String[] cols = criteriaQuery.getColumns( propertyName, criteria ); - return ( distinct ? buildCountDistinctParameterList( cols ) : Arrays.asList( cols ) ); - } - - @SuppressWarnings("unchecked") - private List buildCountDistinctParameterList(String[] cols) { - final List params = new ArrayList( cols.length + 1 ); - params.add( "distinct" ); - params.addAll( Arrays.asList( cols ) ); - return params; - } - - /** - * Sets the count as being distinct - * - * @return {@code this}, for method chaining - */ - public CountProjection setDistinct() { - distinct = true; - return this; - } - - @Override - public String toString() { - if ( distinct ) { - return "distinct " + super.toString(); - } - else { - return super.toString(); - } - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaQuery.java b/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaQuery.java deleted file mode 100755 index 3dbebe2e9d..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaQuery.java +++ /dev/null @@ -1,203 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.type.Type; - -/** - * An instance of CriteriaQuery is passed to criterion, - * order and projection instances when actually compiling and - * executing the query. This interface is not used by application - * code. - * - * @author Gavin King - */ -public interface CriteriaQuery { - /** - * Provides access to the SessionFactory - * - * @return The SessionFactory - */ - public SessionFactoryImplementor getFactory(); - - /** - * Resolve a property path to the name of the column it maps to. Ignores projection aliases. - * - * @param criteria The overall criteria - * @param propertyPath The property path to resolve - * - * @return The column name - * - * @throws HibernateException if the property maps to more than 1 column, or if the property could not be resolved - * - * @see #getColumns - */ - public String getColumn(Criteria criteria, String propertyPath) throws HibernateException; - - /** - * Resolve a property path to the names of the columns it maps to. Ignores projection aliases - * - * @param criteria The criteria - * @param propertyPath The property path to resolve - * - * @return The column names - * - * @throws HibernateException if the property maps to more than 1 column, or if the property could not be resolved - */ - public String[] getColumns(String propertyPath, Criteria criteria) throws HibernateException; - - /** - * Get the names of the columns mapped by a property path; if the property path is not found in criteria, try - * the "outer" query. Projection aliases are ignored. - * - * @param criteria The criteria - * @param propertyPath The property path to resolve - * - * @return The column names - * - * @throws HibernateException if the property could not be resolved - */ - public String[] findColumns(String propertyPath, Criteria criteria) throws HibernateException; - - /** - * Get the type of a property path. - * - * @param criteria The criteria - * @param propertyPath The property path to resolve - * - * @return The type - * - * @throws HibernateException if the property could not be resolved - */ - public Type getType(Criteria criteria, String propertyPath) throws HibernateException; - - /** - * Get the names of the columns mapped by a property path. Here, the property path can refer to - * a projection alias. - * - * @param criteria The criteria - * @param propertyPath The property path to resolve or projection alias - * - * @return The column names - * - * @throws HibernateException if the property/alias could not be resolved - */ - public String[] getColumnsUsingProjection(Criteria criteria, String propertyPath) throws HibernateException; - - /** - * Get the type of a property path. Here, the property path can refer to a projection alias. - * - * @param criteria The criteria - * @param propertyPath The property path to resolve or projection alias - * - * @return The type - * - * @throws HibernateException if the property/alias could not be resolved - */ - public Type getTypeUsingProjection(Criteria criteria, String propertyPath) throws HibernateException; - - /** - * Build a typed-value for the property/value combo. Essentially the same as manually building a TypedValue - * using the given value and the resolved type using {@link #getTypeUsingProjection}. - * - * @param criteria The criteria query - * @param propertyPath The property path/alias to resolve to type. - * @param value The value - * - * @return The TypedValue - * - * @throws HibernateException if the property/alias could not be resolved - */ - public TypedValue getTypedValue(Criteria criteria, String propertyPath, Object value) throws HibernateException; - - /** - * Get the entity name of an entity - * - * @param criteria The criteria - * - * @return The entity name - */ - public String getEntityName(Criteria criteria); - - /** - * Get the entity name of an entity, taking into account the qualifier of the property path - * - * @param criteria The criteria - * @param propertyPath The property path that (supposedly) references an entity - * - * @return The entity name - */ - public String getEntityName(Criteria criteria, String propertyPath); - - /** - * Get the root table alias of an entity - * - * @param criteria The criteria - * - * @return The SQL table alias for the given criteria - */ - public String getSQLAlias(Criteria criteria); - - /** - * Get the root table alias of an entity, taking into account - * the qualifier of the property path - * - * @param criteria The criteria - * @param propertyPath The property path whose SQL alias should be returned. - * - * @return The SQL table alias for the given criteria - */ - public String getSQLAlias(Criteria criteria, String propertyPath); - - /** - * Get the property name, given a possibly qualified property name - * - * @param propertyName The (possibly qualified) property name - * - * @return The simple property name - */ - public String getPropertyName(String propertyName); - - /** - * Get the identifier column names of this entity - * - * @param criteria The criteria - * - * @return The identifier column names - */ - public String[] getIdentifierColumns(Criteria criteria); - - /** - * Get the identifier type of this entity - * - * @param criteria The criteria - * - * @return The identifier type. - */ - public Type getIdentifierType(Criteria criteria); - - /** - * Build a TypedValue for the given identifier value. - * - * @param criteria The criteria whose identifier is referenced. - * @param value The identifier value - * - * @return The TypedValue - */ - public TypedValue getTypedIdentifierValue(Criteria criteria, Object value); - - /** - * Generate a unique SQL alias - * - * @return The generated alias - */ - public String generateSQLAlias(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java b/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java deleted file mode 100755 index c4c88b53ea..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java +++ /dev/null @@ -1,73 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.sql.JoinType; -import org.hibernate.transform.AliasToEntityMapResultTransformer; -import org.hibernate.transform.DistinctRootEntityResultTransformer; -import org.hibernate.transform.PassThroughResultTransformer; -import org.hibernate.transform.ResultTransformer; -import org.hibernate.transform.RootEntityResultTransformer; - -/** - * Commonality between different types of Criteria. - * - * @author Gavin King - */ -public interface CriteriaSpecification { - - /** - * The alias that refers to the "root" entity of the criteria query. - */ - public static final String ROOT_ALIAS = "this"; - - /** - * Each row of results is a Map from alias to entity instance - */ - public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE; - - /** - * Each row of results is an instance of the root entity - */ - public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE; - - /** - * Each row of results is a distinct instance of the root entity - */ - public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE; - - /** - * This result transformer is selected implicitly by calling setProjection() - */ - public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE; - - /** - * Specifies joining to an entity based on an inner join. - * - * @deprecated use {@link org.hibernate.sql.JoinType#INNER_JOIN} - */ - @Deprecated - public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue(); - - /** - * Specifies joining to an entity based on a full join. - * - * @deprecated use {@link org.hibernate.sql.JoinType#FULL_JOIN} - */ - @Deprecated - public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue(); - - /** - * Specifies joining to an entity based on a left outer join. - * - * @deprecated use {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN} - */ - @Deprecated - public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue(); - - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Criterion.java b/hibernate-core/src/main/java/org/hibernate/criterion/Criterion.java deleted file mode 100644 index b790a514ea..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Criterion.java +++ /dev/null @@ -1,50 +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 . - */ -package org.hibernate.criterion; - -import java.io.Serializable; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; - -/** - * An object-oriented representation of a query criterion that may be used - * as a restriction in a Criteria query. - * Built-in criterion types are provided by the Restrictions factory - * class. This interface might be implemented by application classes that - * define custom restriction criteria. - * - * @see Restrictions - * @see Criteria - * @author Gavin King - */ -public interface Criterion extends Serializable { - - /** - * Render the SQL fragment - * - * @param criteria The local criteria - * @param criteriaQuery The overal criteria query - * - * @return The generated SQL fragment - * @throws org.hibernate.HibernateException Problem during rendering. - */ - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException; - - /** - * Return typed values for all parameters in the rendered SQL fragment - * - * @param criteria The local criteria - * @param criteriaQuery The overal criteria query - * - * @return The types values (for binding) - * @throws HibernateException Problem determining types. - */ - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException; - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/DetachedCriteria.java b/hibernate-core/src/main/java/org/hibernate/criterion/DetachedCriteria.java deleted file mode 100755 index f81a5fcfec..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/DetachedCriteria.java +++ /dev/null @@ -1,442 +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 . - */ -package org.hibernate.criterion; - -import java.io.Serializable; - -import org.hibernate.Criteria; -import org.hibernate.FetchMode; -import org.hibernate.LockMode; -import org.hibernate.Session; -import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.internal.CriteriaImpl; -import org.hibernate.sql.JoinType; -import org.hibernate.transform.ResultTransformer; - -/** - * Models a detached form of a Criteria (not associated with a Session). - * - * Some applications need to create criteria queries in "detached mode", where the Hibernate Session is - * not available. Applications would create a DetachableCriteria to describe the query, and then later - * associated it with a Session to obtain the "executable" Criteria: - * - * DetachedCriteria detached = new DetachedCriteria(); - * ... - * Criteria criteria = detached.getExecutableCriteria( session ); - * ... - * criteria.list(); - * - * - * All methods have the same semantics and behavior as the corresponding methods of the Criteria interface. - * - * @author Gavin King - * - * @see org.hibernate.Criteria - */ -public class DetachedCriteria implements CriteriaSpecification, Serializable { - private final CriteriaImpl impl; - private final Criteria criteria; - - protected DetachedCriteria(String entityName) { - impl = new CriteriaImpl( entityName, null ); - criteria = impl; - } - - protected DetachedCriteria(String entityName, String alias) { - impl = new CriteriaImpl( entityName, alias, null ); - criteria = impl; - } - - protected DetachedCriteria(CriteriaImpl impl, Criteria criteria) { - this.impl = impl; - this.criteria = criteria; - } - - /** - * Get an executable instance of Criteria to actually run the query. - * - * @param session The session to associate the built Criteria with - * - * @return The "executable" Criteria - */ - public Criteria getExecutableCriteria(Session session) { - impl.setSession( (SessionImplementor) session ); - return impl; - } - - /** - * Obtain the alias associated with this DetachedCriteria - * - * @return The alias - */ - public String getAlias() { - return criteria.getAlias(); - } - - /** - * Retrieve the CriteriaImpl used internally to hold the DetachedCriteria state - * - * @return The internally maintained CriteriaImpl - */ - CriteriaImpl getCriteriaImpl() { - return impl; - } - - /** - * Static builder to create a DetachedCriteria for the given entity. - * - * @param entityName The name of the entity to create a DetachedCriteria for - * - * @return The DetachedCriteria - */ - @SuppressWarnings("UnusedDeclaration") - public static DetachedCriteria forEntityName(String entityName) { - return new DetachedCriteria( entityName ); - } - - /** - * Static builder to create a DetachedCriteria for the given entity. - * - * @param entityName The name of the entity to create a DetachedCriteria for - * @param alias The alias to apply to the entity - * - * @return The DetachedCriteria - */ - @SuppressWarnings("UnusedDeclaration") - public static DetachedCriteria forEntityName(String entityName, String alias) { - return new DetachedCriteria( entityName, alias ); - } - - /** - * Static builder to create a DetachedCriteria for the given entity, by its Class. - * - * @param clazz The entity class - * - * @return The DetachedCriteria - */ - public static DetachedCriteria forClass(Class clazz) { - return new DetachedCriteria( clazz.getName() ); - } - - /** - * Static builder to create a DetachedCriteria for the given entity, by its Class. - * - * @param clazz The entity class - * @param alias The alias to apply to the entity - * - * @return The DetachedCriteria - */ - public static DetachedCriteria forClass(Class clazz, String alias) { - return new DetachedCriteria( clazz.getName() , alias ); - } - - /** - * Add a restriction - * - * @param criterion The restriction - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria add(Criterion criterion) { - criteria.add( criterion ); - return this; - } - - /** - * Adds an ordering - * - * @param order The ordering - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria addOrder(Order order) { - criteria.addOrder( order ); - return this; - } - - /** - * Set the fetch mode for a given association - * - * @param associationPath The association path - * @param mode The fetch mode to apply - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setFetchMode(String associationPath, FetchMode mode) { - criteria.setFetchMode( associationPath, mode ); - return this; - } - - /** - * Set the projection to use. - * - * @param projection The projection to use - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setProjection(Projection projection) { - criteria.setProjection( projection ); - return this; - } - - /** - * Set the result transformer to use. - * - * @param resultTransformer The result transformer to use - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setResultTransformer(ResultTransformer resultTransformer) { - criteria.setResultTransformer( resultTransformer ); - return this; - } - - /** - * Creates an association path alias within this DetachedCriteria. The alias can then be used in further - * alias creations or restrictions, etc. - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria createAlias(String associationPath, String alias) { - criteria.createAlias( associationPath, alias ); - return this; - } - - /** - * Creates an association path alias within this DetachedCriteria specifying the type of join. The alias - * can then be used in further alias creations or restrictions, etc. - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * @param joinType The type of join to use - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria createAlias(String associationPath, String alias, JoinType joinType) { - criteria.createAlias( associationPath, alias, joinType ); - return this; - } - - /** - * Creates an association path alias within this DetachedCriteria specifying the type of join. The alias - * can then be used in further alias creations or restrictions, etc. - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * @param joinType The type of join to use - * @param withClause An additional restriction on the join - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) { - criteria.createAlias( associationPath, alias, joinType, withClause ); - return this; - } - - /** - * Deprecated! - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * @param joinType The type of join to use - * - * @return {@code this}, for method chaining - * - * @deprecated use {@link #createAlias(String, String, JoinType)} - */ - @Deprecated - public DetachedCriteria createAlias(String associationPath, String alias, int joinType) { - return createAlias( associationPath, alias, JoinType.parse( joinType ) ); - } - - /** - * Deprecated! - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * @param joinType The type of join to use - * @param withClause An additional restriction on the join - * - * @return {@code this}, for method chaining - * - * @deprecated use {@link #createAlias(String, String, JoinType, Criterion)} - */ - @Deprecated - public DetachedCriteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) { - return createAlias( associationPath, alias, JoinType.parse( joinType ), withClause ); - } - - /** - * Creates a nested DetachedCriteria representing the association path. - * - * @param associationPath The association path - * @param alias The alias to apply to that association path - * - * @return the newly created, nested DetachedCriteria - */ - public DetachedCriteria createCriteria(String associationPath, String alias) { - return new DetachedCriteria( impl, criteria.createCriteria( associationPath, alias ) ); - } - - /** - * Creates a nested DetachedCriteria representing the association path. - * - * @param associationPath The association path - * - * @return the newly created, nested DetachedCriteria - */ - public DetachedCriteria createCriteria(String associationPath) { - return new DetachedCriteria( impl, criteria.createCriteria( associationPath ) ); - } - - /** - * Creates a nested DetachedCriteria representing the association path, specifying the type of join to use. - * - * @param associationPath The association path - * @param joinType The type of join to use - * - * @return the newly created, nested DetachedCriteria - */ - public DetachedCriteria createCriteria(String associationPath, JoinType joinType) { - return new DetachedCriteria( impl, criteria.createCriteria( associationPath, joinType ) ); - } - - /** - * Creates a nested DetachedCriteria representing the association path, specifying the type of join to use. - * - * @param associationPath The association path - * @param alias The alias to associate with this "join". - * @param joinType The type of join to use - * - * @return the newly created, nested DetachedCriteria - */ - public DetachedCriteria createCriteria(String associationPath, String alias, JoinType joinType) { - return new DetachedCriteria( impl, criteria.createCriteria( associationPath, alias, joinType ) ); - } - - /** - * Creates a nested DetachedCriteria representing the association path, specifying the type of join to use and - * an additional join restriction. - * - * @param associationPath The association path - * @param alias The alias to associate with this "join". - * @param joinType The type of join to use - * @param withClause The additional join restriction - * - * @return the newly created, nested DetachedCriteria - */ - public DetachedCriteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) { - return new DetachedCriteria(impl, criteria.createCriteria( associationPath, alias, joinType, withClause ) ); - } - - /** - * Deprecated! - * - * @param associationPath The association path - * @param joinType The type of join to use - * - * @return the newly created, nested DetachedCriteria - * - * @deprecated use {@link #createCriteria(String, JoinType)} - */ - @Deprecated - public DetachedCriteria createCriteria(String associationPath, int joinType) { - return createCriteria( associationPath, JoinType.parse( joinType ) ); - } - - /** - * Deprecated! - * - * @param associationPath The association path - * @param alias The alias - * @param joinType The type of join to use - * - * @return the newly created, nested DetachedCriteria - * - * @deprecated use {@link #createCriteria(String, String, JoinType)} - */ - @Deprecated - public DetachedCriteria createCriteria(String associationPath, String alias, int joinType) { - return createCriteria( associationPath, alias, JoinType.parse( joinType ) ); - } - - /** - * Deprecated! - * - * @param associationPath The association path - * @param alias The alias to associate with this "join". - * @param joinType The type of join to use - * @param withClause The additional join restriction - * - * @return the newly created, nested DetachedCriteria - * - * @deprecated use {@link #createCriteria(String, String, JoinType, Criterion)} - */ - @Deprecated - public DetachedCriteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause) { - return createCriteria( associationPath, alias, JoinType.parse( joinType ), withClause ); - } - - /** - * Set the SQL comment to use. - * - * @param comment The SQL comment to use - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setComment(String comment) { - criteria.setComment( comment ); - return this; - } - - /** - * Set the lock mode to use. - * - * @param lockMode The lock mode to use - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setLockMode(LockMode lockMode) { - criteria.setLockMode( lockMode ); - return this; - } - - /** - * Set an alias-specific lock mode. The specified lock mode applies only to that alias. - * - * @param alias The alias to apply the lock to - * @param lockMode The lock mode to use. - * - * @return {@code this}, for method chaining - */ - public DetachedCriteria setLockMode(String alias, LockMode lockMode) { - criteria.setLockMode( alias, lockMode ); - return this; - } - - /** - * Set a timeout for the underlying JDBC query. - * - * @param timeout The timeout value to apply. - * @return this (for method chaining) - * - * @see java.sql.Statement#setQueryTimeout - */ - public DetachedCriteria setTimeout(int timeout) { - criteria.setTimeout( timeout ); - return this; - } - - @Override - public String toString() { - return "DetachableCriteria(" + criteria.toString() + ')'; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Disjunction.java b/hibernate-core/src/main/java/org/hibernate/criterion/Disjunction.java deleted file mode 100644 index 7e5fbe384f..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Disjunction.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.criterion; - -/** - * Defines a disjunction (OR series). - * - * @author Gavin King - * @author Steve Ebersole - * - * @see Conjunction - */ -public class Disjunction extends Junction { - /** - * Constructs a Disjunction - */ - protected Disjunction() { - super( Nature.OR ); - } - - protected Disjunction(Criterion[] conditions) { - super( Nature.OR, conditions ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Distinct.java b/hibernate-core/src/main/java/org/hibernate/criterion/Distinct.java deleted file mode 100755 index 194bfa6f77..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Distinct.java +++ /dev/null @@ -1,87 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.type.Type; - -/** - * A wrappedProjection that is a wrapper around other projections to apply distinction. - * - * @author Gavin King - */ -public class Distinct implements EnhancedProjection { - private final Projection wrappedProjection; - - /** - * Constructs a Distinct - * - * @param wrappedProjection The wrapped projection - */ - public Distinct(Projection wrappedProjection) { - this.wrappedProjection = wrappedProjection; - } - - @Override - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) { - return "distinct " + wrappedProjection.toSqlString( criteria, position, criteriaQuery ); - } - - @Override - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return wrappedProjection.toGroupSqlString( criteria, criteriaQuery ); - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) { - return wrappedProjection.getTypes( criteria, criteriaQuery ); - } - - @Override - public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) { - return wrappedProjection.getTypes( alias, criteria, criteriaQuery ); - } - - @Override - public String[] getColumnAliases(int loc) { - return wrappedProjection.getColumnAliases( loc ); - } - - @Override - public String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - return wrappedProjection instanceof EnhancedProjection - ? ( (EnhancedProjection) wrappedProjection).getColumnAliases( loc, criteria, criteriaQuery ) - : getColumnAliases( loc ); - } - - @Override - public String[] getColumnAliases(String alias, int loc) { - return wrappedProjection.getColumnAliases( alias, loc ); - } - - @Override - public String[] getColumnAliases(String alias, int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - return wrappedProjection instanceof EnhancedProjection - ? ( (EnhancedProjection) wrappedProjection).getColumnAliases( alias, loc, criteria, criteriaQuery ) - : getColumnAliases( alias, loc ); - } - - @Override - public String[] getAliases() { - return wrappedProjection.getAliases(); - } - - @Override - public boolean isGrouped() { - return wrappedProjection.isGrouped(); - } - - @Override - public String toString() { - return "distinct " + wrappedProjection.toString(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/EmptyExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/EmptyExpression.java deleted file mode 100755 index 108ec16835..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/EmptyExpression.java +++ /dev/null @@ -1,30 +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 . - */ -package org.hibernate.criterion; - -/** - * An expression asserting that a collection property is empty - * - * @author Gavin King - */ -public class EmptyExpression extends AbstractEmptinessExpression implements Criterion { - /** - * Constructs an EmptyExpression - * - * @param propertyName The collection property name - * - * @see Restrictions#isEmpty - */ - protected EmptyExpression(String propertyName) { - super( propertyName ); - } - - @Override - protected boolean excludeEmpty() { - return false; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/EnhancedProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/EnhancedProjection.java deleted file mode 100644 index dca87b31f2..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/EnhancedProjection.java +++ /dev/null @@ -1,47 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; - -/** - * An "enhanced" Projection for a {@link Criteria} query. - * - * @author Gail Badner - * @see Projection - * @see Criteria - */ -public interface EnhancedProjection extends Projection { - - /** - * Get the SQL column aliases used by this projection for the columns it writes for inclusion into the - * SELECT clause ({@link #toSqlString}. Hibernate always uses column aliases to extract data from the - * JDBC {@link java.sql.ResultSet}, so it is important that these be implemented correctly in order for - * Hibernate to be able to extract these val;ues correctly. - * - * @param position Just as in {@link #toSqlString}, represents the number of columns rendered - * prior to this projection. - * @param criteria The local criteria to which this project is attached (for resolution). - * @param criteriaQuery The overall criteria query instance. - * @return The columns aliases. - */ - public String[] getColumnAliases(int position, Criteria criteria, CriteriaQuery criteriaQuery); - - /** - * Get the SQL column aliases used by this projection for the columns it writes for inclusion into the - * SELECT clause ({@link #toSqlString} for a particular criteria-level alias. - * - * @param alias The criteria-level alias - * @param position Just as in {@link #toSqlString}, represents the number of columns rendered - * prior to this projection. - * @param criteria The local criteria to which this project is attached (for resolution). - * @param criteriaQuery The overall criteria query instance. - * @return The columns aliases pertaining to a particular criteria-level alias; expected to return null if - * this projection does not understand this alias. - */ - public String[] getColumnAliases(String alias, int position, Criteria criteria, CriteriaQuery criteriaQuery); -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Example.java b/hibernate-core/src/main/java/org/hibernate/criterion/Example.java deleted file mode 100644 index 58a290e215..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Example.java +++ /dev/null @@ -1,484 +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 . - */ -package org.hibernate.criterion; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; - -import org.hibernate.Criteria; -import org.hibernate.EntityMode; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.type.CompositeType; -import org.hibernate.type.Type; - -/** - * Support for query by example. - * - *

- * List results = session.createCriteria(Parent.class)
- *     .add( Example.create(parent).ignoreCase() )
- *     .createCriteria("child")
- *         .add( Example.create( parent.getChild() ) )
- *     .list();
- * 
- * - * "Examples" may be mixed and matched with "Expressions" in the same Criteria. - * - * @see org.hibernate.Criteria - * @author Gavin King - */ - -public class Example implements Criterion { - private final Object exampleEntity; - private PropertySelector selector; - - private boolean isLikeEnabled; - private Character escapeCharacter; - private boolean isIgnoreCaseEnabled; - private MatchMode matchMode; - - private final Set excludedProperties = new HashSet(); - - /** - * Create a new Example criterion instance, which includes all non-null properties by default - * - * @param exampleEntity The example bean to use. - * - * @return a new instance of Example - */ - public static Example create(Object exampleEntity) { - if ( exampleEntity == null ) { - throw new NullPointerException( "null example entity" ); - } - return new Example( exampleEntity, NotNullPropertySelector.INSTANCE ); - } - - /** - * Allow subclasses to instantiate as needed. - * - * @param exampleEntity The example bean - * @param selector The property selector to use - */ - protected Example(Object exampleEntity, PropertySelector selector) { - this.exampleEntity = exampleEntity; - this.selector = selector; - } - - /** - * Set escape character for "like" clause if like matching was enabled - * - * @param escapeCharacter The escape character - * - * @return {@code this}, for method chaining - * - * @see #enableLike - */ - public Example setEscapeCharacter(Character escapeCharacter) { - this.escapeCharacter = escapeCharacter; - return this; - } - - /** - * Use the "like" operator for all string-valued properties. This form implicitly uses {@link MatchMode#EXACT} - * - * @return {@code this}, for method chaining - */ - public Example enableLike() { - return enableLike( MatchMode.EXACT ); - } - - /** - * Use the "like" operator for all string-valued properties - * - * @param matchMode The match mode to use. - * - * @return {@code this}, for method chaining - */ - public Example enableLike(MatchMode matchMode) { - this.isLikeEnabled = true; - this.matchMode = matchMode; - return this; - } - - /** - * Ignore case for all string-valued properties - * - * @return {@code this}, for method chaining - */ - public Example ignoreCase() { - this.isIgnoreCaseEnabled = true; - return this; - } - - /** - * Set the property selector to use. - * - * The property selector operates separate from excluding a property. - * - * @param selector The selector to use - * - * @return {@code this}, for method chaining - * - * @see #excludeProperty - */ - public Example setPropertySelector(PropertySelector selector) { - this.selector = selector; - return this; - } - - /** - * Exclude zero-valued properties. - * - * Equivalent to calling {@link #setPropertySelector} passing in {@link NotNullOrZeroPropertySelector#INSTANCE} - * - * @return {@code this}, for method chaining - * - * @see #setPropertySelector - */ - public Example excludeZeroes() { - setPropertySelector( NotNullOrZeroPropertySelector.INSTANCE ); - return this; - } - - /** - * Include all properties. - * - * Equivalent to calling {@link #setPropertySelector} passing in {@link AllPropertySelector#INSTANCE} - * - * @return {@code this}, for method chaining - * - * @see #setPropertySelector - */ - public Example excludeNone() { - setPropertySelector( AllPropertySelector.INSTANCE ); - return this; - } - - /** - * Exclude a particular property by name. - * - * @param name The name of the property to exclude - * - * @return {@code this}, for method chaining - * - * @see #setPropertySelector - */ - public Example excludeProperty(String name) { - excludedProperties.add( name ); - return this; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - final StringBuilder buf = new StringBuilder().append( '(' ); - final EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( - criteriaQuery.getEntityName( criteria ) - ); - final String[] propertyNames = meta.getPropertyNames(); - final Type[] propertyTypes = meta.getPropertyTypes(); - - final Object[] propertyValues = meta.getPropertyValues( exampleEntity ); - for ( int i=0; i list = new ArrayList(); - for ( int i=0; i list) { - if ( value != null ) { - if ( value instanceof String ) { - String string = (String) value; - if ( isIgnoreCaseEnabled ) { - string = string.toLowerCase(Locale.ROOT); - } - if ( isLikeEnabled ) { - string = matchMode.toMatchString( string ); - } - value = string; - } - list.add( new TypedValue( type, value ) ); - } - } - - protected void addComponentTypedValues( - String path, - Object component, - CompositeType type, - List list, - Criteria criteria, - CriteriaQuery criteriaQuery) { - if ( component != null ) { - final String[] propertyNames = type.getPropertyNames(); - final Type[] subtypes = type.getSubtypes(); - final Object[] values = type.getPropertyValues( component, getEntityMode( criteria, criteriaQuery ) ); - for ( int i=0; i. - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; - -/** - * Expression that checks the existence of rows in a sub-query - * - * @author Gavin King - */ -public class ExistsSubqueryExpression extends SubqueryExpression { - /** - * Constructs the ExistsSubqueryExpression - * - * @param quantifier The "exists"/"not exists" sub-query quantifier - * @param dc The DetachedCriteria representing the sub-query - * - * @see Subqueries#exists - * @see Subqueries#notExists - */ - protected ExistsSubqueryExpression(String quantifier, DetachedCriteria dc) { - super( null, quantifier, dc ); - } - - @Override - protected String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery) { - return ""; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Expression.java b/hibernate-core/src/main/java/org/hibernate/criterion/Expression.java deleted file mode 100644 index e982027292..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Expression.java +++ /dev/null @@ -1,74 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.type.Type; - -/** - * Factory for Criterion objects. Deprecated! - * - * @author Gavin King - * - * @see Restrictions - * - * @deprecated Use {@link Restrictions} instead - */ -@Deprecated -public final class Expression extends Restrictions { - /** - * Apply a constraint expressed in SQL, with JDBC parameters. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The sql - * @param values The parameter values - * @param types The parameter types - * - * @return Criterion - * - * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object[], Type[])} - */ - @Deprecated - public static Criterion sql(String sql, Object[] values, Type[] types) { - return new SQLCriterion( sql, values, types ); - } - - /** - * Apply a constraint expressed in SQL, with a JDBC parameter. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The sql - * @param value The parameter value - * @param type The parameter type - * - * @return Criterion - * - * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object, Type)} - */ - @Deprecated - public static Criterion sql(String sql, Object value, Type type) { - return new SQLCriterion( sql, value, type ); - } - - /** - * Apply a constraint expressed in SQL with no parameters. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The sql - * - * @return Criterion - * - * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String)} - */ - @Deprecated - public static Criterion sql(String sql) { - return new SQLCriterion( sql ); - } - - private Expression() { - //cannot be instantiated - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java deleted file mode 100755 index 0be51d5ce1..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java +++ /dev/null @@ -1,53 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * An identifier constraint - * - * @author Gavin King - */ -public class IdentifierEqExpression implements Criterion { - private final Object value; - - /** - * Constructs an IdentifierEqExpression - * - * @param value The identifier value - * - * @see Restrictions#idEq - */ - protected IdentifierEqExpression(Object value) { - this.value = value; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - final String[] columns = criteriaQuery.getIdentifierColumns( criteria ); - - String result = String.join( " and ", StringHelper.suffix( columns, " = ?" ) ); - if ( columns.length > 1) { - result = '(' + result + ')'; - } - return result; - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - return new TypedValue[] { criteriaQuery.getTypedIdentifierValue( criteria, value ) }; - } - - @Override - public String toString() { - return "id = " + value; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierProjection.java deleted file mode 100755 index 5d45c4d6dc..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/IdentifierProjection.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.type.Type; - -/** - * A property value, or grouped property value - * - * @author Gavin King - */ -public class IdentifierProjection extends SimpleProjection { - private boolean grouped; - - /** - * Constructs a non-grouped identifier projection - * - * @see Projections#id - */ - protected IdentifierProjection() { - this( false ); - } - - /** - * - * Not used externally - */ - private IdentifierProjection(boolean grouped) { - this.grouped = grouped; - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) { - return new Type[] { criteriaQuery.getIdentifierType( criteria ) }; - } - - @Override - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) { - final StringBuilder buf = new StringBuilder(); - final String[] cols = criteriaQuery.getIdentifierColumns( criteria ); - for ( int i=0; i. - */ -package org.hibernate.criterion; - -import java.util.Locale; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.PostgreSQL81Dialect; -import org.hibernate.dialect.PostgreSQLDialect; -import org.hibernate.engine.spi.TypedValue; - -/** - * A case-insensitive "like". - * - * @author Gavin King - * - * @deprecated Prefer {@link LikeExpression} which now has case-insensitivity capability. - */ -@Deprecated -@SuppressWarnings({"deprecation", "UnusedDeclaration"}) -public class IlikeExpression implements Criterion { - private final String propertyName; - private final Object value; - - protected IlikeExpression(String propertyName, Object value) { - this.propertyName = propertyName; - this.value = value; - } - - protected IlikeExpression(String propertyName, String value, MatchMode matchMode) { - this( propertyName, matchMode.toMatchString( value ) ); - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - final Dialect dialect = criteriaQuery.getFactory().getDialect(); - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - if ( columns.length != 1 ) { - throw new HibernateException( "ilike may only be used with single-column properties" ); - } - if ( dialect instanceof PostgreSQLDialect || dialect instanceof PostgreSQL81Dialect) { - return columns[0] + " ilike ?"; - } - else { - return dialect.getLowercaseFunction() + '(' + columns[0] + ") like ?"; - } - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - return new TypedValue[] { - criteriaQuery.getTypedValue( - criteria, - propertyName, - value.toString().toLowerCase(Locale.ROOT) - ) - }; - } - - @Override - public String toString() { - return propertyName + " ilike " + value; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/InExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/InExpression.java deleted file mode 100644 index d255529399..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/InExpression.java +++ /dev/null @@ -1,98 +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 . - */ -package org.hibernate.criterion; - -import java.util.ArrayList; - -import org.hibernate.Criteria; -import org.hibernate.EntityMode; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.type.CompositeType; -import org.hibernate.type.Type; - -/** - * Constrains the property to a specified list of values - * - * @author Gavin King - */ -public class InExpression implements Criterion { - private final String propertyName; - private final Object[] values; - - /** - * Constructs an InExpression - * - * @param propertyName The property name to check - * @param values The values to check against - * - * @see Restrictions#in(String, java.util.Collection) - * @see Restrictions#in(String, Object...) - */ - protected InExpression(String propertyName, Object[] values) { - this.propertyName = propertyName; - this.values = values; - } - - @Override - public String toSqlString( Criteria criteria, CriteriaQuery criteriaQuery ) { - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - if ( criteriaQuery.getFactory().getDialect().supportsRowValueConstructorSyntaxInInList() || columns.length <= 1 ) { - String singleValueParam = StringHelper.repeat( "?, ", columns.length - 1 ) + "?"; - if ( columns.length > 1 ) { - singleValueParam = '(' + singleValueParam + ')'; - } - final String params = values.length > 0 - ? StringHelper.repeat( singleValueParam + ", ", values.length - 1 ) + singleValueParam - : ""; - String cols = String.join( ", ", columns ); - if ( columns.length > 1 ) { - cols = '(' + cols + ')'; - } - return cols + " in (" + params + ')'; - } - else { - String cols = " ( " + String.join( " = ? and ", columns ) + "= ? ) "; - cols = values.length > 0 - ? StringHelper.repeat( cols + "or ", values.length - 1 ) + cols - : ""; - cols = " ( " + cols + " ) "; - return cols; - } - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - final ArrayList list = new ArrayList(); - final Type type = criteriaQuery.getTypeUsingProjection( criteria, propertyName ); - if ( type.isComponentType() ) { - final CompositeType compositeType = (CompositeType) type; - final Type[] subTypes = compositeType.getSubtypes(); - for ( Object value : values ) { - for ( int i = 0; i < subTypes.length; i++ ) { - final Object subValue = value == null - ? null - : compositeType.getPropertyValues( value, EntityMode.POJO )[i]; - list.add( new TypedValue( subTypes[i], subValue ) ); - } - } - } - else { - for ( Object value : values ) { - list.add( criteriaQuery.getTypedValue( criteria, propertyName, value ) ); - } - } - - return list.toArray( new TypedValue[ list.size() ] ); - } - - @Override - public String toString() { - return propertyName + " in (" + StringHelper.toString( values ) + ')'; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Junction.java b/hibernate-core/src/main/java/org/hibernate/criterion/Junction.java deleted file mode 100644 index e78ca47d35..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Junction.java +++ /dev/null @@ -1,122 +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 . - */ -package org.hibernate.criterion; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * A sequence of a logical expressions combined by some - * associative logical operator - * - * @author Gavin King - * @author Steve Ebersole - */ -public class Junction implements Criterion { - private final Nature nature; - private final List conditions = new ArrayList(); - - protected Junction(Nature nature) { - this.nature = nature; - } - - protected Junction(Nature nature, Criterion... criterion) { - this( nature ); - Collections.addAll( conditions, criterion ); - } - - /** - * Adds a criterion to the junction (and/or) - * - * @param criterion The criterion to add - * - * @return {@code this}, for method chaining - */ - public Junction add(Criterion criterion) { - conditions.add( criterion ); - return this; - } - - public Nature getNature() { - return nature; - } - - /** - * Access the conditions making up the junction - * - * @return the criterion - */ - public Iterable conditions() { - return conditions; - } - - @Override - public TypedValue[] getTypedValues(Criteria crit, CriteriaQuery criteriaQuery) throws HibernateException { - final ArrayList typedValues = new ArrayList(); - for ( Criterion condition : conditions ) { - final TypedValue[] subValues = condition.getTypedValues( crit, criteriaQuery ); - Collections.addAll( typedValues, subValues ); - } - return typedValues.toArray( new TypedValue[ typedValues.size() ] ); - } - - @Override - public String toSqlString(Criteria crit, CriteriaQuery criteriaQuery) throws HibernateException { - if ( conditions.size()==0 ) { - return "1=1"; - } - - final StringBuilder buffer = new StringBuilder().append( '(' ); - final Iterator itr = conditions.iterator(); - while ( itr.hasNext() ) { - buffer.append( ( (Criterion) itr.next() ).toSqlString( crit, criteriaQuery ) ); - if ( itr.hasNext() ) { - buffer.append( ' ' ) - .append( nature.getOperator() ) - .append( ' ' ); - } - } - - return buffer.append( ')' ).toString(); - } - - @Override - public String toString() { - return '(' + StringHelper.join( ' ' + nature.getOperator() + ' ', conditions.iterator() ) + ')'; - } - - /** - * The type of junction - */ - public static enum Nature { - /** - * An AND - */ - AND, - /** - * An OR - */ - OR; - - /** - * The corresponding SQL operator - * - * @return SQL operator - */ - public String getOperator() { - return name().toLowerCase(Locale.ROOT); - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/LikeExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/LikeExpression.java deleted file mode 100644 index e266a70d78..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/LikeExpression.java +++ /dev/null @@ -1,85 +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 . - */ -package org.hibernate.criterion; - -import java.util.Locale; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.dialect.Dialect; -import org.hibernate.engine.spi.TypedValue; - -/** - * A criterion representing a "like" expression - * - * @author Scott Marlow - * @author Steve Ebersole - */ -public class LikeExpression implements Criterion { - private final String propertyName; - private final Object value; - private final Character escapeChar; - private final boolean ignoreCase; - - protected LikeExpression( - String propertyName, - String value, - Character escapeChar, - boolean ignoreCase) { - this.propertyName = propertyName; - this.value = value; - this.escapeChar = escapeChar; - this.ignoreCase = ignoreCase; - } - - protected LikeExpression(String propertyName, String value) { - this( propertyName, value, null, false ); - } - - @SuppressWarnings("UnusedDeclaration") - protected LikeExpression(String propertyName, String value, MatchMode matchMode) { - this( propertyName, matchMode.toMatchString( value ) ); - } - - protected LikeExpression( - String propertyName, - String value, - MatchMode matchMode, - Character escapeChar, - boolean ignoreCase) { - this( propertyName, matchMode.toMatchString( value ), escapeChar, ignoreCase ); - } - - @Override - public String toSqlString(Criteria criteria,CriteriaQuery criteriaQuery) { - final Dialect dialect = criteriaQuery.getFactory().getDialect(); - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - if ( columns.length != 1 ) { - throw new HibernateException( "Like may only be used with single-column properties" ); - } - - final String escape = escapeChar == null ? "" : " escape \'" + escapeChar + "\'"; - final String column = columns[0]; - if ( ignoreCase ) { - if ( dialect.supportsCaseInsensitiveLike() ) { - return column +" " + dialect.getCaseInsensitiveLike() + " ?" + escape; - } - else { - return dialect.getLowercaseFunction() + '(' + column + ')' + " like ?" + escape; - } - } - else { - return column + " like ?" + escape; - } - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - final String matchValue = ignoreCase ? value.toString().toLowerCase(Locale.ROOT) : value.toString(); - - return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, matchValue ) }; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/LogicalExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/LogicalExpression.java deleted file mode 100644 index 527b7a2cf8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/LogicalExpression.java +++ /dev/null @@ -1,58 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.engine.spi.TypedValue; - -/** - * Superclass of binary logical expressions - * - * @author Gavin King - */ -public class LogicalExpression implements Criterion { - private final Criterion lhs; - private final Criterion rhs; - private final String op; - - protected LogicalExpression(Criterion lhs, Criterion rhs, String op) { - this.lhs = lhs; - this.rhs = rhs; - this.op = op; - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - final TypedValue[] lhsTypedValues = lhs.getTypedValues( criteria, criteriaQuery ); - final TypedValue[] rhsTypedValues = rhs.getTypedValues( criteria, criteriaQuery ); - - final TypedValue[] result = new TypedValue[ lhsTypedValues.length + rhsTypedValues.length ]; - System.arraycopy( lhsTypedValues, 0, result, 0, lhsTypedValues.length ); - System.arraycopy( rhsTypedValues, 0, result, lhsTypedValues.length, rhsTypedValues.length ); - return result; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return '(' - + lhs.toSqlString( criteria, criteriaQuery ) - + ' ' - + getOp() - + ' ' - + rhs.toSqlString( criteria, criteriaQuery ) - + ')'; - } - - public String getOp() { - return op; - } - - @Override - public String toString() { - return lhs.toString() + ' ' + getOp() + ' ' + rhs.toString(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/MatchMode.java b/hibernate-core/src/main/java/org/hibernate/criterion/MatchMode.java deleted file mode 100644 index 73caa7b4c8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/MatchMode.java +++ /dev/null @@ -1,66 +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 . - */ -package org.hibernate.criterion; - -/** - * Represents a strategy for matching strings using "like". - * - * @author Gavin King - * @see Example#enableLike(MatchMode) - */ -public enum MatchMode { - - /** - * Match the entire string to the pattern - */ - EXACT { - @Override - public String toMatchString(String pattern) { - return pattern; - } - }, - - /** - * Match the start of the string to the pattern - */ - START { - @Override - public String toMatchString(String pattern) { - return pattern + '%'; - } - }, - - /** - * Match the end of the string to the pattern - */ - END { - @Override - public String toMatchString(String pattern) { - return '%' + pattern; - } - }, - - /** - * Match the pattern anywhere in the string - */ - ANYWHERE { - @Override - public String toMatchString(String pattern) { - return '%' + pattern + '%'; - } - }; - - /** - * Convert the pattern, by appending/prepending "%" - * - * @param pattern The pattern for convert according to the mode - * - * @return The converted pattern - */ - public abstract String toMatchString(String pattern); - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java b/hibernate-core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java deleted file mode 100755 index 2c9f2afaa8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java +++ /dev/null @@ -1,74 +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 . - */ -package org.hibernate.criterion; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; - -/** - * An expression pertaining to an entity's defined natural identifier - * - * @author Gavin King - * - * @see org.hibernate.Session#byNaturalId(Class) - * @see org.hibernate.Session#byNaturalId(String) - * @see org.hibernate.Session#bySimpleNaturalId(Class) - * @see org.hibernate.Session#bySimpleNaturalId(String) - */ -public class NaturalIdentifier implements Criterion { - private final Conjunction conjunction = new Conjunction(); - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return conjunction.getTypedValues( criteria, criteriaQuery ); - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return conjunction.toSqlString( criteria, criteriaQuery ); - } - - /** - * Get a map of set of the natural identifier values set on this criterion (for composite natural identifiers - * this need not be the full set of properties). - * - * @return The value map. - */ - public Map getNaturalIdValues() { - final Map naturalIdValueMap = new ConcurrentHashMap(); - for ( Criterion condition : conjunction.conditions() ) { - if ( !SimpleExpression.class.isInstance( condition ) ) { - continue; - } - final SimpleExpression equalsCondition = SimpleExpression.class.cast( condition ); - if ( !"=".equals( equalsCondition.getOp() ) ) { - continue; - } - - naturalIdValueMap.put( equalsCondition.getPropertyName(), equalsCondition.getValue() ); - } - return naturalIdValueMap; - } - - /** - * Set a natural identifier value for this expression - * - * @param property The specific property name - * @param value The value to use - * - * @return {@code this}, for method chaining - */ - public NaturalIdentifier set(String property, Object value) { - conjunction.add( Restrictions.eq( property, value ) ); - return this; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java deleted file mode 100755 index c80ec8efde..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java +++ /dev/null @@ -1,31 +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 . - */ -package org.hibernate.criterion; - -/** - * An expression asserting that a collection property is empty - * - * @author Gavin King - */ -public class NotEmptyExpression extends AbstractEmptinessExpression implements Criterion { - /** - * Constructs an EmptyExpression - * - * @param propertyName The collection property name - * - * @see Restrictions#isNotEmpty - */ - protected NotEmptyExpression(String propertyName) { - super( propertyName ); - } - - @Override - protected boolean excludeEmpty() { - return true; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/NotExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/NotExpression.java deleted file mode 100644 index 164e5b0766..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/NotExpression.java +++ /dev/null @@ -1,48 +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 . - */ -package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; - -/** - * A criterion that is a wrapper for another, negating the wrapped one. - * - * @author Gavin King - */ -public class NotExpression implements Criterion { - private Criterion criterion; - - /** - * Constructs a NotExpression - * - * @param criterion The expression to wrap and negate - * - * @see Restrictions#not - */ - protected NotExpression(Criterion criterion) { - this.criterion = criterion; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return criteriaQuery.getFactory().getDialect().getNotExpression( - criterion.toSqlString( criteria, criteriaQuery ) - ); - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return criterion.getTypedValues( criteria, criteriaQuery ); - } - - @Override - public String toString() { - return "not " + criterion.toString(); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/NotNullExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/NotNullExpression.java deleted file mode 100644 index ce4e4ea57b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/NotNullExpression.java +++ /dev/null @@ -1,51 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * Constrains a property to be non-null - * - * @author Gavin King - */ -public class NotNullExpression implements Criterion { - private static final TypedValue[] NO_VALUES = new TypedValue[0]; - - private final String propertyName; - - protected NotNullExpression(String propertyName) { - this.propertyName = propertyName; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - String result = String.join( - " or ", - StringHelper.suffix( columns, " is not null" ) - ); - if ( columns.length > 1 ) { - result = '(' + result + ')'; - } - return result; - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return NO_VALUES; - } - - @Override - public String toString() { - return propertyName + " is not null"; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/NullExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/NullExpression.java deleted file mode 100644 index 8a28f717c4..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/NullExpression.java +++ /dev/null @@ -1,57 +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 . - */ -package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * Constrains a property to be null - * - * @author Gavin King - */ -public class NullExpression implements Criterion { - private static final TypedValue[] NO_VALUES = new TypedValue[0]; - - private final String propertyName; - - /** - * Constructs a NullExpression - * - * @param propertyName The name of the property to check for null - * - * @see Restrictions#isNull - */ - protected NullExpression(String propertyName) { - this.propertyName = propertyName; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - String result = String.join( - " and ", - StringHelper.suffix( columns, " is null" ) - ); - if ( columns.length > 1 ) { - result = '(' + result + ')'; - } - return result; - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return NO_VALUES; - } - - @Override - public String toString() { - return propertyName + " is null"; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Order.java b/hibernate-core/src/main/java/org/hibernate/criterion/Order.java deleted file mode 100644 index efd4730e29..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Order.java +++ /dev/null @@ -1,156 +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 . - */ -package org.hibernate.criterion; - -import java.io.Serializable; -import java.sql.Types; -import java.util.Locale; - -import org.hibernate.Criteria; -import org.hibernate.NullPrecedence; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.type.Type; - -/** - * Represents an ordering imposed upon the results of a Criteria - * - * @author Gavin King - * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) - */ -public class Order implements Serializable { - private boolean ascending; - private boolean ignoreCase; - private String propertyName; - private NullPrecedence nullPrecedence; - - /** - * Ascending order - * - * @param propertyName The property to order on - * - * @return The build Order instance - */ - public static Order asc(String propertyName) { - return new Order( propertyName, true ); - } - - /** - * Descending order. - * - * @param propertyName The property to order on - * - * @return The build Order instance - */ - public static Order desc(String propertyName) { - return new Order( propertyName, false ); - } - - /** - * Constructor for Order. Order instances are generally created by factory methods. - * - * @see #asc - * @see #desc - */ - protected Order(String propertyName, boolean ascending) { - this.propertyName = propertyName; - this.ascending = ascending; - } - - /** - * Should this ordering ignore case? Has no effect on non-character properties. - * - * @return {@code this}, for method chaining - */ - public Order ignoreCase() { - ignoreCase = true; - return this; - } - - /** - * Defines precedence for nulls. - * - * @param nullPrecedence The null precedence to use - * - * @return {@code this}, for method chaining - */ - public Order nulls(NullPrecedence nullPrecedence) { - this.nullPrecedence = nullPrecedence; - return this; - } - - public String getPropertyName() { - return propertyName; - } - - @SuppressWarnings("UnusedDeclaration") - public boolean isAscending() { - return ascending; - } - - @SuppressWarnings("UnusedDeclaration") - public boolean isIgnoreCase() { - return ignoreCase; - } - - - /** - * Render the SQL fragment - * - * @param criteria The criteria - * @param criteriaQuery The overall query - * - * @return The ORDER BY fragment for this ordering - */ - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - final String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName ); - final Type type = criteriaQuery.getTypeUsingProjection( criteria, propertyName ); - final SessionFactoryImplementor factory = criteriaQuery.getFactory(); - final int[] sqlTypes = type.sqlTypes( factory ); - - final StringBuilder fragment = new StringBuilder(); - for ( int i=0; i. - */ -package org.hibernate.criterion; - -import org.hibernate.type.Type; - -/** - * @author Steve Ebersole - */ -public interface ParameterInfoCollector { - void addNamedParameter(String name, Type type); - void addPositionalParameter(int label, Type type); -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Projection.java b/hibernate-core/src/main/java/org/hibernate/criterion/Projection.java deleted file mode 100644 index e41c9584ea..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Projection.java +++ /dev/null @@ -1,119 +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 . - */ -package org.hibernate.criterion; - -import java.io.Serializable; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.type.Type; - -/** - * An object-oriented representation of a query result set projection in a {@link Criteria} query. - * Built-in projection types are provided by the {@link Projections} factory class. This interface might be - * implemented by application classes that define custom projections. - * - * @author Gavin King - * @author Steve Ebersole - * - * @see Projections - * @see Criteria - */ -public interface Projection extends Serializable { - - /** - * Render the SQL fragment to be used in the SELECT clause. - * - * @param criteria The local criteria to which this project is attached (for resolution). - * @param position The number of columns rendered in the SELECT clause before this projection. Generally - * speaking this is useful to ensure uniqueness of the individual columns aliases. - * @param criteriaQuery The overall criteria query instance. - * @return The SQL fragment to plug into the SELECT - * @throws HibernateException Indicates a problem performing the rendering - */ - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) - throws HibernateException; - - /** - * Render the SQL fragment to be used in the GROUP BY clause - * - * @param criteria The local criteria to which this project is attached (for resolution). - * @param criteriaQuery The overall criteria query instance. - * @return The SQL fragment to plug into the GROUP BY - * @throws HibernateException Indicates a problem performing the rendering - */ - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException; - - /** - * Types returned by the rendered SQL {@link #toSqlString fragment}. In other words what are the types - * that would represent the values this projection asked to be pulled into the result set? - * - * @param criteria The local criteria to which this project is attached (for resolution). - * @param criteriaQuery The overall criteria query instance. - * @return The return types. - * @throws HibernateException Indicates a problem resolving the types - */ - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException; - - /** - * Get the return types for a particular user-visible alias. - *

- * Differs from {@link #getTypes(org.hibernate.Criteria, CriteriaQuery)} in that here we are only interested in - * the types related to the given criteria-level alias. - * - * @param alias The criteria-level alias for which to find types. - * @param criteria The local criteria to which this project is attached (for resolution). - * @param criteriaQuery The overall criteria query instance. - * @return The return types; expected to return null if this projection does not understand this alias. - * @throws HibernateException Indicates a problem resolving the types - */ - public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException; - - - /** - * Get the SQL column aliases used by this projection for the columns it writes for inclusion into the - * SELECT clause ({@link #toSqlString}. Hibernate always uses column aliases to extract data from the - * JDBC {@link java.sql.ResultSet}, so it is important that these be implemented correctly in order for - * Hibernate to be able to extract these val;ues correctly. - * - * @param position Just as in {@link #toSqlString}, represents the number of columns rendered - * prior to this projection. - * @return The columns aliases. - */ - public String[] getColumnAliases(int position); - - /** - * Get the SQL column aliases used by this projection for the columns it writes for inclusion into the - * SELECT clause ({@link #toSqlString} for a particular criteria-level alias. - * - * @param alias The criteria-level alias - * @param position Just as in {@link #toSqlString}, represents the number of columns rendered - * prior to this projection. - * @return The columns aliases pertaining to a particular criteria-level alias; expected to return null if - * this projection does not understand this alias. - */ - public String[] getColumnAliases(String alias, int position); - - /** - * Get the criteria-level aliases for this projection (ie. the ones that will be passed to the - * {@link org.hibernate.transform.ResultTransformer}) - * - * @return The aliases - */ - public String[] getAliases(); - - /** - * Is this projection fragment (SELECT clause) also part of the GROUP BY - * - * @return True if the projection is also part of the GROUP BY; false otherwise. - */ - public boolean isGrouped(); - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/ProjectionList.java b/hibernate-core/src/main/java/org/hibernate/criterion/ProjectionList.java deleted file mode 100644 index f54b6b889b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/ProjectionList.java +++ /dev/null @@ -1,225 +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 . - */ -package org.hibernate.criterion; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.type.Type; - -/** - * A projection that wraps other projections to allow selecting multiple values. - * - * @author Gavin King - */ -public class ProjectionList implements EnhancedProjection { - private List elements = new ArrayList(); - - /** - * Constructs a ProjectionList - * - * @see Projections#projectionList() - */ - protected ProjectionList() { - } - - /** - * Lol - * - * @return duh - * - * @deprecated an instance factory method does not make sense - * - * @see Projections#projectionList() - */ - @Deprecated - public ProjectionList create() { - return new ProjectionList(); - } - - /** - * Add a projection to this list of projections - * - * @param projection The projection to add - * - * @return {@code this}, for method chaining - */ - public ProjectionList add(Projection projection) { - elements.add( projection ); - return this; - } - - /** - * Adds a projection to this list of projections after wrapping it with an alias - * - * @param projection The projection to add - * @param alias The alias to apply to the projection - * - * @return {@code this}, for method chaining - * - * @see Projections#alias - */ - public ProjectionList add(Projection projection, String alias) { - return add( Projections.alias( projection, alias ) ); - } - - @Override - public boolean isGrouped() { - for ( Projection projection : elements ) { - if ( projection.isGrouped() ) { - return true; - } - } - return false; - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final List types = new ArrayList( getLength() ); - for ( Projection projection : elements ) { - final Type[] elemTypes = projection.getTypes( criteria, criteriaQuery ); - Collections.addAll( types, elemTypes ); - } - return types.toArray( new Type[types.size()] ); - } - - @Override - public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException { - final StringBuilder buf = new StringBuilder(); - String separator = ""; - - for ( Projection projection : elements ) { - buf.append( separator ).append( projection.toSqlString( criteria, loc, criteriaQuery ) ); - loc += getColumnAliases( loc, criteria, criteriaQuery, projection ).length; - separator = ", "; - } - return buf.toString(); - } - - @Override - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final StringBuilder buf = new StringBuilder(); - String separator = ""; - for ( Projection projection : elements ) { - if ( ! projection.isGrouped() ) { - continue; - } - - buf.append( separator ).append( projection.toGroupSqlString( criteria, criteriaQuery ) ); - separator = ", "; - } - return buf.toString(); - } - - @Override - public String[] getColumnAliases(final int loc) { - int position = loc; - final List result = new ArrayList( getLength() ); - for ( Projection projection : elements ) { - final String[] aliases = projection.getColumnAliases( position ); - Collections.addAll( result, aliases ); - position += aliases.length; - } - return result.toArray( new String[ result.size() ] ); - } - - @Override - public String[] getColumnAliases(final int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - int position = loc; - final List result = new ArrayList( getLength() ); - for ( Projection projection : elements ) { - final String[] aliases = getColumnAliases( position, criteria, criteriaQuery, projection ); - Collections.addAll( result, aliases ); - position += aliases.length; - } - return result.toArray( new String[result.size()] ); - } - - @Override - public String[] getColumnAliases(String alias, final int loc) { - int position = loc; - for ( Projection projection : elements ) { - final String[] aliases = projection.getColumnAliases( alias, position ); - if ( aliases != null ) { - return aliases; - } - position += projection.getColumnAliases( position ).length; - } - return null; - } - - @Override - public String[] getColumnAliases(String alias, int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - int position = loc; - for ( Projection projection : elements ) { - final String[] aliases = getColumnAliases( alias, position, criteria, criteriaQuery, projection ); - if ( aliases != null ) { - return aliases; - } - position += getColumnAliases( position, criteria, criteriaQuery, projection ).length; - } - return null; - } - - private static String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery, Projection projection) { - return projection instanceof EnhancedProjection - ? ( (EnhancedProjection) projection ).getColumnAliases( loc, criteria, criteriaQuery ) - : projection.getColumnAliases( loc ); - } - - private static String[] getColumnAliases(String alias, int loc, Criteria criteria, CriteriaQuery criteriaQuery, Projection projection) { - return projection instanceof EnhancedProjection - ? ( (EnhancedProjection) projection ).getColumnAliases( alias, loc, criteria, criteriaQuery ) - : projection.getColumnAliases( alias, loc ); - } - - @Override - public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) { - for ( Projection projection : elements ) { - final Type[] types = projection.getTypes( alias, criteria, criteriaQuery ); - if ( types != null ) { - return types; - } - } - return null; - } - - @Override - public String[] getAliases() { - final List result = new ArrayList( getLength() ); - for ( Projection projection : elements ) { - final String[] aliases = projection.getAliases(); - Collections.addAll( result, aliases ); - } - return result.toArray( new String[result.size()] ); - } - - /** - * Access a wrapped projection by index - * - * @param i The index of the projection to return - * - * @return The projection - */ - @SuppressWarnings("UnusedDeclaration") - public Projection getProjection(int i) { - return elements.get( i ); - } - - public int getLength() { - return elements.size(); - } - - @Override - public String toString() { - return elements.toString(); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Projections.java b/hibernate-core/src/main/java/org/hibernate/criterion/Projections.java deleted file mode 100755 index e2826eb793..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Projections.java +++ /dev/null @@ -1,225 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.type.Type; - -/** - * The criterion package may be used by applications as a framework for building - * new kinds of Projection. However, it is intended that most applications will - * simply use the built-in projection types via the static factory methods of this class. - * - * The factory methods that take an alias allow the projected value to be referred to by - * criterion and order instances. - * - * See also the {@link Restrictions} factory methods for generating {@link Criterion} instances - * - * @author Gavin King - * @author Steve Ebersole - * - * @see org.hibernate.Criteria - */ -public final class Projections { - /** - * A property value projection - * - * @param propertyName The name of the property whose values should be projected - * - * @return The property projection - * - * @see PropertyProjection - */ - public static PropertyProjection property(String propertyName) { - return new PropertyProjection( propertyName ); - } - - /** - * A grouping property value projection - * - * @param propertyName The name of the property to group - * - * @return The grouped projection - * - * @see PropertyProjection - */ - public static PropertyProjection groupProperty(String propertyName) { - return new PropertyProjection( propertyName, true ); - } - - /** - * An identifier value projection. - * - * @return The identifier projection - * - * @see IdentifierProjection - */ - public static IdentifierProjection id() { - return new IdentifierProjection(); - } - - /** - * Create a distinct projection from a projection. - * - * @param projection The project to treat distinctly - * - * @return The distinct projection - * - * @see Distinct - */ - public static Projection distinct(Projection projection) { - return new Distinct( projection ); - } - - /** - * Create a new projection list. - * - * @return The projection list - */ - public static ProjectionList projectionList() { - return new ProjectionList(); - } - - /** - * The query row count, ie. count(*) - * - * @return The projection representing the row count - * - * @see RowCountProjection - */ - public static Projection rowCount() { - return new RowCountProjection(); - } - - /** - * A property value count projection - * - * @param propertyName The name of the property to count over - * - * @return The count projection - * - * @see CountProjection - */ - public static CountProjection count(String propertyName) { - return new CountProjection( propertyName ); - } - - /** - * A distinct property value count projection - * - * @param propertyName The name of the property to count over - * - * @return The count projection - * - * @see CountProjection - */ - public static CountProjection countDistinct(String propertyName) { - return new CountProjection( propertyName ).setDistinct(); - } - - /** - * A property maximum value projection - * - * @param propertyName The property for which to find the max - * - * @return the max projection - * - * @see AggregateProjection - */ - public static AggregateProjection max(String propertyName) { - return new AggregateProjection( "max", propertyName ); - } - - /** - * A property minimum value projection - * - * @param propertyName The property for which to find the min - * - * @return the min projection - * - * @see AggregateProjection - */ - public static AggregateProjection min(String propertyName) { - return new AggregateProjection( "min", propertyName ); - } - - /** - * A property average value projection - * - * @param propertyName The property over which to find the average - * - * @return the avg projection - * - * @see AvgProjection - */ - public static AggregateProjection avg(String propertyName) { - return new AvgProjection( propertyName ); - } - - /** - * A property value sum projection - * - * @param propertyName The property over which to sum - * - * @return the sum projection - * - * @see AggregateProjection - */ - public static AggregateProjection sum(String propertyName) { - return new AggregateProjection( "sum", propertyName ); - } - - /** - * Assign an alias to a projection, by wrapping it - * - * @param projection The projection to be aliased - * @param alias The alias to apply - * - * @return The aliased projection - * - * @see AliasedProjection - */ - public static Projection alias(Projection projection, String alias) { - return new AliasedProjection( projection, alias ); - } - - /** - * A SQL projection, a typed select clause fragment - * - * @param sql The SQL fragment - * @param columnAliases The column aliases - * @param types The resulting types - * - * @return The SQL projection - * - * @see SQLProjection - */ - public static Projection sqlProjection(String sql, String[] columnAliases, Type[] types) { - return new SQLProjection( sql, columnAliases, types ); - } - - /** - * A grouping SQL projection, specifying both select clause and group by clause fragments - * - * @param sql The SQL SELECT fragment - * @param groupBy The SQL GROUP BY fragment - * @param columnAliases The column aliases - * @param types The resulting types - * - * @return The SQL projection - * - * @see SQLProjection - */ - @SuppressWarnings("UnusedDeclaration") - public static Projection sqlGroupProjection(String sql, String groupBy, String[] columnAliases, Type[] types) { - return new SQLProjection(sql, groupBy, columnAliases, types); - } - - private Projections() { - //cannot be instantiated - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/PropertiesSubqueryExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/PropertiesSubqueryExpression.java deleted file mode 100644 index e6b9c4b6fa..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/PropertiesSubqueryExpression.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; - -/** - * A comparison between several properties value in the outer query and the result of a multicolumn subquery. - * - * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) - */ -public class PropertiesSubqueryExpression extends SubqueryExpression { - private final String[] propertyNames; - - protected PropertiesSubqueryExpression(String[] propertyNames, String op, DetachedCriteria dc) { - super( op, null, dc ); - this.propertyNames = propertyNames; - } - - @Override - protected String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery) { - final StringBuilder left = new StringBuilder( "(" ); - final String[] sqlColumnNames = new String[propertyNames.length]; - for ( int i = 0; i < sqlColumnNames.length; ++i ) { - sqlColumnNames[i] = outerQuery.getColumn( criteria, propertyNames[i] ); - } - left.append( String.join( ", ", sqlColumnNames ) ); - return left.append( ")" ).toString(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Property.java b/hibernate-core/src/main/java/org/hibernate/criterion/Property.java deleted file mode 100755 index 9d1478fd40..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Property.java +++ /dev/null @@ -1,741 +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 . - */ -package org.hibernate.criterion; - -import java.util.Collection; - -/** - * A factory for property-specific criterion and projection instances - * - * @author Gavin King - * @author Steve Ebersole - */ -public class Property extends PropertyProjection { - /** - * Factory for Property instances. - * - * @param propertyName The name of the property. - * - * @return The Property instance - */ - public static Property forName(String propertyName) { - return new Property( propertyName ); - } - - /** - * Constructs a Property. non-private to allow subclassing. - * - * @param propertyName The property name. - */ - protected Property(String propertyName) { - super( propertyName ); - } - - /** - * Creates a BETWEEN restriction for this property between the given min and max - * - * @param min The minimum - * @param max The maximum - * - * @return The BETWEEN restriction - * - * @see Restrictions#between(String, Object, Object) - */ - public Criterion between(Object min, Object max) { - return Restrictions.between( getPropertyName(), min, max ); - } - - /** - * Creates an IN restriction for this property based on the given list of literals - * - * @param values The literal values - * - * @return The IN restriction - * - * @see Restrictions#in(String, Collection) - */ - public Criterion in(Collection values) { - return Restrictions.in( getPropertyName(), values ); - } - - /** - * Creates an IN restriction for this property based on the given list of literals - * - * @param values The literal values - * - * @return The IN restriction - * - * @see Restrictions#in(String, Object[]) - */ - public Criterion in(Object... values) { - return Restrictions.in( getPropertyName(), values ); - } - - /** - * Creates a LIKE restriction for this property - * - * @param value The value to like compare with - * - * @return The LIKE restriction - * - * @see Restrictions#like(String, Object) - */ - public SimpleExpression like(Object value) { - return Restrictions.like( getPropertyName(), value ); - } - - /** - * Creates a LIKE restriction for this property - * - * @param value The value to like compare with - * @param matchMode The match mode to apply to the LIKE - * - * @return The LIKE restriction - * - * @see Restrictions#like(String, String, MatchMode) - */ - public SimpleExpression like(String value, MatchMode matchMode) { - return Restrictions.like( getPropertyName(), value, matchMode ); - } - - /** - * Creates an equality restriction. - * - * @param value The value to check against - * - * @return The equality restriction. - * - * @see Restrictions#eq(String, Object) - */ - public SimpleExpression eq(Object value) { - return Restrictions.eq( getPropertyName(), value ); - } - - /** - * Creates an equality restriction capable of also rendering as IS NULL if the given value is {@code null} - * - * @param value The value to check against - * - * @return The equality restriction. - * - * @see Restrictions#eqOrIsNull(String, Object) - * @see #eq - * @see #isNull - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion eqOrIsNull(Object value) { - return Restrictions.eqOrIsNull( getPropertyName(), value ); - } - - /** - * Creates a non-equality restriction. - * - * @param value The value to check against - * - * @return The non-equality restriction. - * - * @see Restrictions#ne(String, Object) - */ - public SimpleExpression ne(Object value) { - return Restrictions.ne( getPropertyName(), value ); - } - - /** - * Creates a non-equality restriction capable of also rendering as IS NOT NULL if the given value is {@code null} - * - * @param value The value to check against - * - * @return The non-equality restriction. - * - * @see Restrictions#neOrIsNotNull(String, Object) - * @see #ne - * @see #isNotNull - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion neOrIsNotNull(Object value) { - return Restrictions.neOrIsNotNull( getPropertyName(), value ); - } - - /** - * Create a greater-than restriction based on this property - * - * @param value The value to check against - * - * @return The greater-than restriction - * - * @see Restrictions#gt(String, Object) - */ - public SimpleExpression gt(Object value) { - return Restrictions.gt( getPropertyName(), value ); - } - - /** - * Create a less-than restriction based on this property - * - * @param value The value to check against - * - * @return The less-than restriction - * - * @see Restrictions#lt(String, Object) - */ - public SimpleExpression lt(Object value) { - return Restrictions.lt( getPropertyName(), value ); - } - - /** - * Create a less-than-or-equal-to restriction based on this property - * - * @param value The value to check against - * - * @return The less-than-or-equal-to restriction - * - * @see Restrictions#le(String, Object) - */ - public SimpleExpression le(Object value) { - return Restrictions.le( getPropertyName(), value ); - } - - /** - * Create a greater-than-or-equal-to restriction based on this property - * - * @param value The value to check against - * - * @return The greater-than-or-equal-to restriction - * - * @see Restrictions#ge(String, Object) - */ - public SimpleExpression ge(Object value) { - return Restrictions.ge( getPropertyName(), value ); - } - - /** - * Creates an equality restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#eqProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression eqProperty(Property other) { - return Restrictions.eqProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates an equality restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#eqProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression eqProperty(String other) { - return Restrictions.eqProperty( getPropertyName(), other ); - } - - /** - * Creates a non-equality restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#neProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression neProperty(Property other) { - return Restrictions.neProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates a non-equality restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#neProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression neProperty(String other) { - return Restrictions.neProperty( getPropertyName(), other ); - } - - /** - * Creates a less-than-or-equal-to restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#leProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression leProperty(Property other) { - return Restrictions.leProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates a less-than-or-equal-to restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#leProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression leProperty(String other) { - return Restrictions.leProperty( getPropertyName(), other ); - } - - /** - * Creates a greater-than-or-equal-to restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#geProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression geProperty(Property other) { - return Restrictions.geProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates a greater-than-or-equal-to restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#geProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression geProperty(String other) { - return Restrictions.geProperty( getPropertyName(), other ); - } - - /** - * Creates a less-than restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#ltProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression ltProperty(Property other) { - return Restrictions.ltProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates a less-than restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#ltProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression ltProperty(String other) { - return Restrictions.ltProperty( getPropertyName(), other ); - } - - /** - * Creates a greater-than restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#geProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression gtProperty(Property other) { - return Restrictions.gtProperty( getPropertyName(), other.getPropertyName() ); - } - - /** - * Creates a greater-than restriction between 2 properties - * - * @param other The other property to compare against - * - * @return The restriction - * - * @see Restrictions#geProperty(String, String) - */ - @SuppressWarnings("UnusedDeclaration") - public PropertyExpression gtProperty(String other) { - return Restrictions.gtProperty( getPropertyName(), other ); - } - - /** - * Creates a NULL restriction - * - * @return The restriction - * - * @see Restrictions#isNull(String) - */ - public Criterion isNull() { - return Restrictions.isNull( getPropertyName() ); - } - - /** - * Creates a NOT NULL restriction - * - * @return The restriction - * - * @see Restrictions#isNotNull(String) - */ - public Criterion isNotNull() { - return Restrictions.isNotNull( getPropertyName() ); - } - - /** - * Creates a restriction to check that a collection is empty - * - * @return The restriction - * - * @see Restrictions#isEmpty(String) - */ - public Criterion isEmpty() { - return Restrictions.isEmpty( getPropertyName() ); - } - - /** - * Creates a restriction to check that a collection is not empty - * - * @return The restriction - * - * @see Restrictions#isNotEmpty(String) - */ - public Criterion isNotEmpty() { - return Restrictions.isNotEmpty( getPropertyName() ); - } - - /** - * Creates a property count projection - * - * @return The projection - * - * @see Projections#count - */ - public CountProjection count() { - return Projections.count( getPropertyName() ); - } - - /** - * Creates a property max projection - * - * @return The projection - * - * @see Projections#max - */ - public AggregateProjection max() { - return Projections.max( getPropertyName() ); - } - - /** - * Creates a property min projection - * - * @return The projection - * - * @see Projections#min - */ - public AggregateProjection min() { - return Projections.min( getPropertyName() ); - } - - /** - * Creates a property avg projection - * - * @return The projection - * - * @see Projections#avg - */ - public AggregateProjection avg() { - return Projections.avg( getPropertyName() ); - } - - /** - * Creates a projection for this property as a group expression - * - * @return The group projection - * - * @see Projections#groupProperty - */ - public PropertyProjection group() { - return Projections.groupProperty( getPropertyName() ); - } - - /** - * Creates an ascending ordering for this property - * - * @return The order - */ - public Order asc() { - return Order.asc( getPropertyName() ); - } - - /** - * Creates a descending ordering for this property - * - * @return The order - */ - public Order desc() { - return Order.desc( getPropertyName() ); - } - - /** - * Get a component attribute of this property. - * - * @param propertyName The sub property name - * - * @return The property - */ - public Property getProperty(String propertyName) { - return forName( getPropertyName() + '.' + propertyName ); - } - - /** - * Creates a sub-query equality expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyEq(String, DetachedCriteria) - */ - public Criterion eq(DetachedCriteria subselect) { - return Subqueries.propertyEq( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query non-equality expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyNe(String, DetachedCriteria) - */ - public Criterion ne(DetachedCriteria subselect) { - return Subqueries.propertyNe( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query less-than expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLt(String, DetachedCriteria) - */ - public Criterion lt(DetachedCriteria subselect) { - return Subqueries.propertyLt( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query less-than-or-equal-to expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLe(String, DetachedCriteria) - */ - public Criterion le(DetachedCriteria subselect) { - return Subqueries.propertyLe( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query greater-than expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGt(String, DetachedCriteria) - */ - public Criterion gt(DetachedCriteria subselect) { - return Subqueries.propertyGt( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query greater-than-or-equal-to expression for this property - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGe(String, DetachedCriteria) - */ - public Criterion ge(DetachedCriteria subselect) { - return Subqueries.propertyGe( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query NOT IN expression for this property. I.e., {@code [prop] NOT IN [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyNotIn(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion notIn(DetachedCriteria subselect) { - return Subqueries.propertyNotIn( getPropertyName(), subselect ); - } - - /** - * Creates a sub-query IN expression for this property. I.e., {@code [prop] IN [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyIn(String, DetachedCriteria) - */ - public Criterion in(DetachedCriteria subselect) { - return Subqueries.propertyIn( getPropertyName(), subselect ); - } - - /** - * Creates a equals-all sub-query expression for this property. I.e., {@code [prop] = ALL [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyEqAll(String, DetachedCriteria) - */ - public Criterion eqAll(DetachedCriteria subselect) { - return Subqueries.propertyEqAll( getPropertyName(), subselect ); - } - - /** - * Creates a greater-than-all sub-query expression for this property. I.e., {@code [prop] > ALL [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGtAll(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion gtAll(DetachedCriteria subselect) { - return Subqueries.propertyGtAll( getPropertyName(), subselect ); - } - - /** - * Creates a less-than-all sub-query expression for this property. I.e., {@code [prop] < ALL [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLtAll(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion ltAll(DetachedCriteria subselect) { - return Subqueries.propertyLtAll( getPropertyName(), subselect ); - } - - /** - * Creates a less-than-or-equal-to-all sub-query expression for this property. I.e., {@code [prop] <= ALL [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLeAll(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion leAll(DetachedCriteria subselect) { - return Subqueries.propertyLeAll( getPropertyName(), subselect ); - } - - /** - * Creates a greater-than-or-equal-to-all sub-query expression for this property. I.e., {@code [prop] >= ALL [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGeAll(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion geAll(DetachedCriteria subselect) { - return Subqueries.propertyGeAll( getPropertyName(), subselect ); - } - - /** - * Creates a greater-than-some sub-query expression for this property. I.e., {@code [prop] > SOME [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGtSome(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion gtSome(DetachedCriteria subselect) { - return Subqueries.propertyGtSome( getPropertyName(), subselect ); - } - - /** - * Creates a less-than-some sub-query expression for this property. I.e., {@code [prop] < SOME [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLtSome(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion ltSome(DetachedCriteria subselect) { - return Subqueries.propertyLtSome( getPropertyName(), subselect ); - } - - /** - * Creates a less-than-or-equal-to-some sub-query expression for this property. I.e., {@code [prop] <= SOME [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyLeSome(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion leSome(DetachedCriteria subselect) { - return Subqueries.propertyLeSome( getPropertyName(), subselect ); - } - - /** - * Creates a greater-than-or-equal-to-some sub-query expression for this property. I.e., {@code [prop] >= SOME [subquery]} - * - * @param subselect The sub-query - * - * @return The expression - * - * @see Subqueries#propertyGeSome(String, DetachedCriteria) - */ - @SuppressWarnings("UnusedDeclaration") - public Criterion geSome(DetachedCriteria subselect) { - return Subqueries.propertyGeSome( getPropertyName(), subselect ); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/PropertyExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/PropertyExpression.java deleted file mode 100644 index 5f2c546404..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/PropertyExpression.java +++ /dev/null @@ -1,60 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; - -/** - * superclass for comparisons between two properties (with SQL binary operators) - * - * @author Gavin King - */ -public class PropertyExpression implements Criterion { - private static final TypedValue[] NO_TYPED_VALUES = new TypedValue[0]; - - private final String propertyName; - private final String otherPropertyName; - private final String op; - - protected PropertyExpression(String propertyName, String otherPropertyName, String op) { - this.propertyName = propertyName; - this.otherPropertyName = otherPropertyName; - this.op = op; - } - - public String getOp() { - return op; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String[] lhsColumns = criteriaQuery.findColumns( propertyName, criteria ); - final String[] rhsColumns = criteriaQuery.findColumns( otherPropertyName, criteria ); - - final String[] comparisons = StringHelper.add( lhsColumns, getOp(), rhsColumns ); - if ( comparisons.length > 1 ) { - return '(' + String.join( " and ", comparisons ) + ')'; - } - else { - return comparisons[0]; - } - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) { - return NO_TYPED_VALUES; - } - - @Override - public String toString() { - return propertyName + getOp() + otherPropertyName; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/PropertyProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/PropertyProjection.java deleted file mode 100755 index a34e70ae42..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/PropertyProjection.java +++ /dev/null @@ -1,76 +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 . - */ -package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.type.Type; - -/** - * A property value, or grouped property value - * - * @author Gavin King - * @author Steve Ebersole - */ -public class PropertyProjection extends SimpleProjection { - private String propertyName; - private boolean grouped; - - protected PropertyProjection(String prop, boolean grouped) { - this.propertyName = prop; - this.grouped = grouped; - } - - protected PropertyProjection(String prop) { - this( prop, false ); - } - - @Override - public boolean isGrouped() { - return grouped; - } - - public String getPropertyName() { - return propertyName; - } - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new Type[] { criteriaQuery.getType( criteria, propertyName ) }; - } - - @Override - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { - final StringBuilder buf = new StringBuilder(); - final String[] cols = criteriaQuery.getColumns( propertyName, criteria ); - for ( int i=0; i. - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; - -/** - * A comparison between a property value in the outer query and the result of a subquery - * - * @author Gavin King - * @author Steve Ebersole - */ -public class PropertySubqueryExpression extends SubqueryExpression { - private String propertyName; - - protected PropertySubqueryExpression(String propertyName, String op, String quantifier, DetachedCriteria dc) { - super( op, quantifier, dc ); - this.propertyName = propertyName; - } - - @Override - protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return criteriaQuery.getColumn( criteria, propertyName ); - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java b/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java deleted file mode 100755 index 264f7f8a9d..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Restrictions.java +++ /dev/null @@ -1,680 +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 . - */ -package org.hibernate.criterion; - -import java.util.Collection; -import java.util.Map; - -import org.hibernate.type.Type; - -/** - * The criterion package may be used by applications as a framework for building - * new kinds of Criterion. However, it is intended that most applications will - * simply use the built-in criterion types via the static factory methods of this class. - * - * See also the {@link Projections} factory methods for generating {@link Projection} instances - * - * @author Gavin King - * @author Steve Ebersole - * - * @see org.hibernate.Criteria - */ -public class Restrictions { - /** - * Apply an "equal" constraint to the identifier property - * - * @param value The value to use in comparison - * - * @return Criterion - * - * @see IdentifierEqExpression - */ - public static Criterion idEq(Object value) { - return new IdentifierEqExpression( value ); - } - /** - * Apply an "equal" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return SimpleExpression - * - * @see SimpleExpression - */ - public static SimpleExpression eq(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, "=" ); - } - - /** - * Apply an "equal" constraint to the named property. If the value - * is null, instead apply "is null". - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see #eq - * @see #isNull - */ - public static Criterion eqOrIsNull(String propertyName, Object value) { - return value == null - ? isNull( propertyName ) - : eq( propertyName, value ); - } - - /** - * Apply a "not equal" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - - * @see SimpleExpression - */ - public static SimpleExpression ne(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, "<>" ); - } - - /** - * Apply a "not equal" constraint to the named property. If the value - * is null, instead apply "is not null". - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see #ne - * @see #isNotNull - */ - public static Criterion neOrIsNotNull(String propertyName, Object value) { - return value == null - ? isNotNull( propertyName ) - : ne( propertyName, value ); - } - - /** - * Apply a "like" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression like(String propertyName, Object value) { - // todo : update this to use LikeExpression - return new SimpleExpression( propertyName, value, " like " ); - } - - /** - * Apply a "like" constraint to the named property using the provided match mode - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * @param matchMode The match mode to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression like(String propertyName, String value, MatchMode matchMode) { - // todo : update this to use LikeExpression - return new SimpleExpression( propertyName, matchMode.toMatchString( value ), " like " ); - } - - /** - * A case-insensitive "like" (similar to Postgres ilike operator) - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see LikeExpression - */ - public static Criterion ilike(String propertyName, Object value) { - if ( value == null ) { - throw new IllegalArgumentException( "Comparison value passed to ilike cannot be null" ); - } - return ilike( propertyName, value.toString(), MatchMode.EXACT ); - } - - /** - * A case-insensitive "like" (similar to Postgres ilike operator) using the provided match mode - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * @param matchMode The match mode to use in comparison - * - * @return The Criterion - * - * @see LikeExpression - */ - public static Criterion ilike(String propertyName, String value, MatchMode matchMode) { - if ( value == null ) { - throw new IllegalArgumentException( "Comparison value passed to ilike cannot be null" ); - } - return new LikeExpression( propertyName, value, matchMode, null, true ); - } - - /** - * Apply a "greater than" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression gt(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, ">" ); - } - - /** - * Apply a "less than" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression lt(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, "<" ); - } - - /** - * Apply a "less than or equal" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression le(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, "<=" ); - } - /** - * Apply a "greater than or equal" constraint to the named property - * - * @param propertyName The name of the property - * @param value The value to use in comparison - * - * @return The Criterion - * - * @see SimpleExpression - */ - public static SimpleExpression ge(String propertyName, Object value) { - return new SimpleExpression( propertyName, value, ">=" ); - } - - /** - * Apply a "between" constraint to the named property - * - * @param propertyName The name of the property - * @param low The low value - * @param high The high value - * - * @return The Criterion - * - * @see BetweenExpression - */ - public static Criterion between(String propertyName, Object low, Object high) { - return new BetweenExpression( propertyName, low, high ); - } - - /** - * Apply an "in" constraint to the named property. - * - * @param propertyName The name of the property - * @param values The literal values to use in the IN restriction - * - * @return The Criterion - * - * @see InExpression - */ - public static Criterion in(String propertyName, Object... values) { - return new InExpression( propertyName, values ); - } - - /** - * Apply an "in" constraint to the named property. - * - * @param propertyName The name of the property - * @param values The literal values to use in the IN restriction - * - * @return The Criterion - * - * @see InExpression - */ - public static Criterion in(String propertyName, Collection values) { - return new InExpression( propertyName, values.toArray() ); - } - - /** - * Apply an "is null" constraint to the named property - * - * @param propertyName The name of the property - * - * @return Criterion - * - * @see NullExpression - */ - public static Criterion isNull(String propertyName) { - return new NullExpression( propertyName ); - } - - /** - * Apply an "is not null" constraint to the named property - * - * @param propertyName The property name - * - * @return The Criterion - * - * @see NotNullExpression - */ - public static Criterion isNotNull(String propertyName) { - return new NotNullExpression( propertyName ); - } - - /** - * Apply an "equal" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression eqProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, "=" ); - } - - /** - * Apply a "not equal" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression neProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, "<>" ); - } - - /** - * Apply a "less than" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression ltProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, "<" ); - } - - /** - * Apply a "less than or equal" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression leProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, "<=" ); - } - - /** - * Apply a "greater than" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression gtProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, ">" ); - } - - /** - * Apply a "greater than or equal" constraint to two properties - * - * @param propertyName One property name - * @param otherPropertyName The other property name - * - * @return The Criterion - * - * @see PropertyExpression - */ - public static PropertyExpression geProperty(String propertyName, String otherPropertyName) { - return new PropertyExpression( propertyName, otherPropertyName, ">=" ); - } - - /** - * Return the conjuction of two expressions - * - * @param lhs One expression - * @param rhs The other expression - * - * @return The Criterion - */ - public static LogicalExpression and(Criterion lhs, Criterion rhs) { - return new LogicalExpression(lhs, rhs, "and"); - } - /** - * Return the conjuction of multiple expressions - * - * @param predicates The predicates making up the initial junction - * - * @return The conjunction - */ - public static Conjunction and(Criterion... predicates) { - return conjunction( predicates ); - } - - /** - * Return the disjuction of two expressions - * - * @param lhs One expression - * @param rhs The other expression - * - * @return The Criterion - */ - public static LogicalExpression or(Criterion lhs, Criterion rhs) { - return new LogicalExpression( lhs, rhs, "or" ); - } - - /** - * Return the disjuction of multiple expressions - * - * @param predicates The predicates making up the initial junction - * - * @return The conjunction - */ - public static Disjunction or(Criterion... predicates) { - return disjunction( predicates ); - } - - /** - * Return the negation of an expression - * - * @param expression The expression to be negated - * - * @return Criterion - * - * @see NotExpression - */ - public static Criterion not(Criterion expression) { - return new NotExpression( expression ); - } - - /** - * Create a restriction expressed in SQL with JDBC parameters. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The SQL restriction - * @param values The parameter values - * @param types The parameter types - * - * @return The Criterion - * - * @see SQLCriterion - */ - public static Criterion sqlRestriction(String sql, Object[] values, Type[] types) { - return new SQLCriterion( sql, values, types ); - } - - /** - * Create a restriction expressed in SQL with one JDBC parameter. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The SQL restriction - * @param value The parameter value - * @param type The parameter type - * - * @return The Criterion - * - * @see SQLCriterion - */ - public static Criterion sqlRestriction(String sql, Object value, Type type) { - return new SQLCriterion( sql, value, type ); - } - - /** - * Apply a constraint expressed in SQL with no JDBC parameters. Any occurrences of {alias} will be - * replaced by the table alias. - * - * @param sql The SQL restriction - * - * @return The Criterion - * - * @see SQLCriterion - */ - public static Criterion sqlRestriction(String sql) { - return new SQLCriterion( sql ); - } - - /** - * Group expressions together in a single conjunction (A and B and C...). - * - * This form creates an empty conjunction. See {@link Conjunction#add(Criterion)} - * - * @return Conjunction - */ - public static Conjunction conjunction() { - return new Conjunction(); - } - - /** - * Group expressions together in a single conjunction (A and B and C...). - * - * @param conditions The initial set of conditions to put into the Conjunction - * - * @return Conjunction - */ - public static Conjunction conjunction(Criterion... conditions) { - return new Conjunction( conditions ); - } - - /** - * Group expressions together in a single disjunction (A or B or C...). - * - * This form creates an empty disjunction. See {@link Disjunction#add(Criterion)} - * - * @return Conjunction - */ - public static Disjunction disjunction() { - return new Disjunction(); - } - - /** - * Group expressions together in a single disjunction (A or B or C...). - * - * @param conditions The initial set of conditions to put into the Disjunction - * - * @return Conjunction - */ - public static Disjunction disjunction(Criterion... conditions) { - return new Disjunction( conditions ); - } - - /** - * Apply an "equals" constraint to each property in the key set of a Map - * - * @param propertyNameValues a map from property names to values - * - * @return Criterion - * - * @see Conjunction - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion allEq(Map propertyNameValues) { - final Conjunction conj = conjunction(); - - for ( Map.Entry entry : propertyNameValues.entrySet() ) { - conj.add( eq( entry.getKey(), entry.getValue() ) ); - } - return conj; - } - - /** - * Constrain a collection valued property to be empty - * - * @param propertyName The name of the collection property - * - * @return The Criterion - * - * @see EmptyExpression - */ - public static Criterion isEmpty(String propertyName) { - return new EmptyExpression( propertyName ); - } - - /** - * Constrain a collection valued property to be non-empty - * - * @param propertyName The name of the collection property - * - * @return The Criterion - * - * @see NotEmptyExpression - */ - public static Criterion isNotEmpty(String propertyName) { - return new NotEmptyExpression( propertyName ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - public static Criterion sizeEq(String propertyName, int size) { - return new SizeExpression( propertyName, size, "=" ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion sizeNe(String propertyName, int size) { - return new SizeExpression( propertyName, size, "<>" ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion sizeGt(String propertyName, int size) { - return new SizeExpression( propertyName, size, "<" ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion sizeLt(String propertyName, int size) { - return new SizeExpression( propertyName, size, ">" ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion sizeGe(String propertyName, int size) { - return new SizeExpression( propertyName, size, "<=" ); - } - - /** - * Constrain a collection valued property by size - * - * @param propertyName The name of the collection property - * @param size The size to use in comparison - * - * @return The Criterion - * - * @see SizeExpression - */ - @SuppressWarnings("UnusedDeclaration") - public static Criterion sizeLe(String propertyName, int size) { - return new SizeExpression( propertyName, size, ">=" ); - } - - /** - * Consider using any of the natural id based loading stuff from session instead, especially in cases - * where the restriction is the full set of natural id values. - * - * @return The Criterion - * - * @see NaturalIdentifier - * - * @see org.hibernate.Session#byNaturalId(Class) - * @see org.hibernate.Session#byNaturalId(String) - * @see org.hibernate.Session#bySimpleNaturalId(Class) - * @see org.hibernate.Session#bySimpleNaturalId(String) - */ - public static NaturalIdentifier naturalId() { - return new NaturalIdentifier(); - } - - protected Restrictions() { - // cannot be instantiated, but needs to be protected so Expression can extend it - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/RowCountProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/RowCountProjection.java deleted file mode 100755 index 26f946ab57..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/RowCountProjection.java +++ /dev/null @@ -1,49 +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 . - */ -package org.hibernate.criterion; - -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.dialect.function.SQLFunctionRegistry; -import org.hibernate.type.Type; - -/** - * A row count - * - * @author Gavin King - */ -public class RowCountProjection extends SimpleProjection { - private static final List ARGS = java.util.Collections.singletonList( "*" ); - - @Override - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final Type countFunctionReturnType = getFunction( criteriaQuery ).getReturnType( null, criteriaQuery.getFactory() ); - return new Type[] { countFunctionReturnType }; - } - - @Override - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { - return getFunction( criteriaQuery ).render( null, ARGS, criteriaQuery.getFactory() ) + " as y" + position + '_'; - } - - protected SQLFunction getFunction(CriteriaQuery criteriaQuery) { - final SQLFunctionRegistry sqlFunctionRegistry = criteriaQuery.getFactory().getSqlFunctionRegistry(); - final SQLFunction function = sqlFunctionRegistry.findSQLFunction( "count" ); - if ( function == null ) { - throw new HibernateException( "Unable to locate count function mapping" ); - } - return function; - } - - @Override - public String toString() { - return "count(*)"; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SQLCriterion.java b/hibernate-core/src/main/java/org/hibernate/criterion/SQLCriterion.java deleted file mode 100644 index 55f9b5b8fb..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SQLCriterion.java +++ /dev/null @@ -1,54 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.type.Type; - -/** - * A SQL fragment. The string {alias} will be replaced by the - * alias of the root entity. - */ -public class SQLCriterion implements Criterion { - private final String sql; - private final TypedValue[] typedValues; - - protected SQLCriterion(String sql, Object[] values, Type[] types) { - this.sql = sql; - this.typedValues = new TypedValue[values.length]; - for ( int i=0; i. - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.internal.util.StringHelper; -import org.hibernate.type.Type; - -/** - * A SQL fragment. The string {alias} will be replaced by the - * alias of the root entity. - */ -public class SQLProjection implements Projection { - private final String sql; - private final String groupBy; - private final Type[] types; - private String[] aliases; - private String[] columnAliases; - private boolean grouped; - - protected SQLProjection(String sql, String[] columnAliases, Type[] types) { - this( sql, null, columnAliases, types ); - } - - protected SQLProjection(String sql, String groupBy, String[] columnAliases, Type[] types) { - this.sql = sql; - this.types = types; - this.aliases = columnAliases; - this.columnAliases = columnAliases; - this.grouped = groupBy!=null; - this.groupBy = groupBy; - } - - @Override - public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) { - return StringHelper.replace( sql, "{alias}", criteriaQuery.getSQLAlias( criteria ) ); - } - - @Override - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return StringHelper.replace( groupBy, "{alias}", criteriaQuery.getSQLAlias( criteria ) ); - } - - @Override - public Type[] getTypes(Criteria crit, CriteriaQuery criteriaQuery) { - return types; - } - - @Override - public String toString() { - return sql; - } - - @Override - public String[] getAliases() { - return aliases; - } - - @Override - public String[] getColumnAliases(int loc) { - return columnAliases; - } - - @Override - public boolean isGrouped() { - return grouped; - } - - @Override - public Type[] getTypes(String alias, Criteria crit, CriteriaQuery criteriaQuery) { - return null; - } - - @Override - public String[] getColumnAliases(String alias, int loc) { - return null; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/SimpleExpression.java deleted file mode 100644 index 5d377d78de..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleExpression.java +++ /dev/null @@ -1,108 +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 . - */ -package org.hibernate.criterion; - -import java.sql.Types; -import java.util.Locale; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.type.Type; - -/** - * superclass for "simple" comparisons (with SQL binary operators) - * - * @author Gavin King - */ -public class SimpleExpression implements Criterion { - private final String propertyName; - private final Object value; - private boolean ignoreCase; - private final String op; - - protected SimpleExpression(String propertyName, Object value, String op) { - this.propertyName = propertyName; - this.value = value; - this.op = op; - } - - protected SimpleExpression(String propertyName, Object value, String op, boolean ignoreCase) { - this.propertyName = propertyName; - this.value = value; - this.ignoreCase = ignoreCase; - this.op = op; - } - - protected final String getOp() { - return op; - } - - public String getPropertyName() { - return propertyName; - } - - public Object getValue() { - return value; - } - - /** - * Make case insensitive. No effect for non-String values - * - * @return {@code this}, for method chaining - */ - public SimpleExpression ignoreCase() { - ignoreCase = true; - return this; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String[] columns = criteriaQuery.findColumns( propertyName, criteria ); - final Type type = criteriaQuery.getTypeUsingProjection( criteria, propertyName ); - final StringBuilder fragment = new StringBuilder(); - - if ( columns.length > 1 ) { - fragment.append( '(' ); - } - final SessionFactoryImplementor factory = criteriaQuery.getFactory(); - final int[] sqlTypes = type.sqlTypes( factory ); - for ( int i = 0; i < columns.length; i++ ) { - final boolean lower = ignoreCase && (sqlTypes[i] == Types.VARCHAR || sqlTypes[i] == Types.CHAR || - sqlTypes[i] == Types.NVARCHAR || sqlTypes[i] == Types.NCHAR); - if ( lower ) { - fragment.append( factory.getDialect().getLowercaseFunction() ).append( '(' ); - } - fragment.append( columns[i] ); - if ( lower ) { - fragment.append( ')' ); - } - - fragment.append( getOp() ).append( "?" ); - if ( i < columns.length - 1 ) { - fragment.append( " and " ); - } - } - if ( columns.length > 1 ) { - fragment.append( ')' ); - } - return fragment.toString(); - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final Object casedValue = ignoreCase ? value.toString().toLowerCase(Locale.ROOT) : value; - return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, casedValue ) }; - } - - @Override - public String toString() { - return propertyName + getOp() + value; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleProjection.java b/hibernate-core/src/main/java/org/hibernate/criterion/SimpleProjection.java deleted file mode 100755 index 56e0d776a7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleProjection.java +++ /dev/null @@ -1,116 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.type.Type; - -/** - * A single-column projection that may be aliased - * - * @author Gavin King - */ -public abstract class SimpleProjection implements EnhancedProjection { - private static final int NUM_REUSABLE_ALIASES = 40; - private static final String[] REUSABLE_ALIASES = initializeReusableAliases(); - - private static String[] initializeReusableAliases() { - final String[] aliases = new String[NUM_REUSABLE_ALIASES]; - for ( int i = 0; i < NUM_REUSABLE_ALIASES; i++ ) { - aliases[i] = aliasForLocation( i ); - } - return aliases; - } - - private static String aliasForLocation(final int loc) { - return "y" + loc + "_"; - } - - private static String getAliasForLocation(final int loc) { - if ( loc >= NUM_REUSABLE_ALIASES ) { - return aliasForLocation( loc ); - } - else { - return REUSABLE_ALIASES[loc]; - } - } - - /** - * Create an aliased form of this projection - * - * @param alias The alias to apply - * - * @return The aliased projection - */ - public Projection as(String alias) { - return Projections.alias( this, alias ); - } - - @Override - public String[] getColumnAliases(String alias, int loc) { - return null; - } - - @Override - public String[] getColumnAliases(String alias, int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - return getColumnAliases( alias, loc ); - } - - @Override - public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) { - return null; - } - - @Override - public String[] getColumnAliases(int loc) { - return new String[] { getAliasForLocation( loc ) }; - } - - /** - * Count the number of columns this projection uses. - * - * @param criteria The criteria - * @param criteriaQuery The query - * - * @return The number of columns - */ - public int getColumnCount(Criteria criteria, CriteriaQuery criteriaQuery) { - final Type[] types = getTypes( criteria, criteriaQuery ); - int count = 0; - for ( Type type : types ) { - count += type.getColumnSpan( criteriaQuery.getFactory() ); - } - return count; - } - - @Override - public String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery) { - final int numColumns = getColumnCount( criteria, criteriaQuery ); - final String[] aliases = new String[ numColumns ]; - for (int i = 0; i < numColumns; i++) { - aliases[i] = getAliasForLocation( loc ); - loc++; - } - return aliases; - } - - @Override - public String[] getAliases() { - return new String[1]; - } - - @Override - public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - throw new UnsupportedOperationException( "not a grouping projection" ); - } - - @Override - public boolean isGrouped() { - return false; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java deleted file mode 100755 index ecd6e8f041..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java +++ /dev/null @@ -1,39 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; - -/** - * A comparison between a constant value and the the result of a subquery - * - * @author Gavin King - */ -public class SimpleSubqueryExpression extends SubqueryExpression { - private Object value; - - protected SimpleSubqueryExpression(Object value, String op, String quantifier, DetachedCriteria dc) { - super( op, quantifier, dc ); - this.value = value; - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final TypedValue[] subQueryTypedValues = super.getTypedValues( criteria, criteriaQuery ); - final TypedValue[] result = new TypedValue[subQueryTypedValues.length+1]; - System.arraycopy( subQueryTypedValues, 0, result, 1, subQueryTypedValues.length ); - result[0] = new TypedValue( getTypes()[0], value ); - return result; - } - - @Override - protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) { - return "?"; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SizeExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/SizeExpression.java deleted file mode 100755 index 82a86ce094..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SizeExpression.java +++ /dev/null @@ -1,68 +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 . - */ -package org.hibernate.criterion; - -import java.util.Locale; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.persister.collection.QueryableCollection; -import org.hibernate.persister.entity.Loadable; -import org.hibernate.sql.ConditionFragment; -import org.hibernate.type.StandardBasicTypes; - -/** - * Used to define a restriction on a collection property based on its size. - * - * @author Gavin King - * @author Steve Ebersole - */ -public class SizeExpression implements Criterion { - private final String propertyName; - private final int size; - private final String op; - - protected SizeExpression(String propertyName, int size, String op) { - this.propertyName = propertyName; - this.size = size; - this.op = op; - } - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final String entityName =criteriaQuery.getEntityName( criteria, propertyName ); - final String role = entityName + '.' + criteriaQuery.getPropertyName( propertyName ); - final QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory().getCollectionPersister( role ); - - final String[] fk = cp.getKeyColumnNames(); - final String[] pk = ( (Loadable) cp.getOwnerEntityPersister() ).getIdentifierColumnNames(); - - final ConditionFragment subQueryRestriction = new ConditionFragment() - .setTableAlias( criteriaQuery.getSQLAlias( criteria, propertyName ) ) - .setCondition( pk, fk ); - - return String.format( - Locale.ROOT, - "? %s (select count(*) from %s where %s)", - op, - cp.getTableName(), - subQueryRestriction.toFragmentString() - ); - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new TypedValue[] { new TypedValue( StandardBasicTypes.INTEGER, size ) }; - } - - @Override - public String toString() { - return Integer.toString(size) + op + propertyName + ".size"; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/Subqueries.java b/hibernate-core/src/main/java/org/hibernate/criterion/Subqueries.java deleted file mode 100755 index 36b84e9b76..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/Subqueries.java +++ /dev/null @@ -1,631 +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 . - */ -package org.hibernate.criterion; - -/** - * Factory class for criterion instances that represent expressions - * involving subqueries. - * - * @see Restrictions - * @see Projection - * @see org.hibernate.Criteria - * - * @author Gavin King - * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) - */ -@SuppressWarnings( {"UnusedDeclaration"}) -public class Subqueries { - - /** - * Creates a criterion which checks for the existence of rows in the subquery result - * - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see ExistsSubqueryExpression - */ - public static Criterion exists(DetachedCriteria dc) { - return new ExistsSubqueryExpression( "exists", dc ); - } - - /** - * Creates a criterion which checks for the non-existence of rows in the subquery result - * - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see ExistsSubqueryExpression - */ - public static Criterion notExists(DetachedCriteria dc) { - return new ExistsSubqueryExpression( "not exists", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property equals ALL the values in the - * subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyEqAll(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than ALL the values in the - * subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyGtAll(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than ALL the values in the - * subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyLtAll(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than-or-equal-to ALL the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyGeAll(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than-or-equal-to ALL the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyLeAll(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than SOME of the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyGtSome(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than SOME of the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyLtSome(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than-or-equal-to SOME of the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyGeSome(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">=", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than-or-equal-to SOME of the - * values in the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyLeSome(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<=", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is in the set of values in the - * subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyIn(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "in", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is not-in the set of values in - * the subquery result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyNotIn(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "not in", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property as being equal to the set of values in - * the subquery result. The implication is that the subquery returns a single result.. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyEq(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "=", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is not equal to the value in the - * subquery result. The assumption is that the subquery returns a single result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - */ - public static Criterion propertyNe(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression(propertyName, "<>", null, dc); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than the value in the - * subquery result. The assumption is that the subquery returns a single result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - * @see #propertyGtAll - * @see #propertyGtSome - */ - public static Criterion propertyGt(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than the value in the - * subquery result. The assumption is that the subquery returns a single result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - * @see #propertyLtAll - * @see #propertyLtSome - */ - public static Criterion propertyLt(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is greater-than-or-equal-to the value - * in the subquery result. The assumption is that the subquery returns a single result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - * @see #propertyGeAll - * @see #propertyGeSome - */ - public static Criterion propertyGe(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, ">=", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given property is less-than-or-equal-to the value - * in the subquery result. The assumption is that the subquery returns a single result. - * - * @param propertyName The name of the property to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertySubqueryExpression - * @see #propertyLeAll - * @see #propertyLeSome - */ - public static Criterion propertyLe(String propertyName, DetachedCriteria dc) { - return new PropertySubqueryExpression( propertyName, "<=", null, dc ); - } - - /** - * Creates a criterion which checks that the value of multiple given properties as being equal to the set of - * values in the subquery result. The implication is that the subquery returns a single result. This form is - * however implicitly using tuple comparisons - * - * @param propertyNames The names of the properties to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertiesSubqueryExpression - */ - public static Criterion propertiesEq(String[] propertyNames, DetachedCriteria dc) { - return new PropertiesSubqueryExpression( propertyNames, "=", dc ); - } - - /** - * Creates a criterion which checks that the value of multiple given properties as being not-equal to the set of - * values in the subquery result. The assumption is that the subquery returns a single result. This form is - * however implicitly using tuple comparisons - * - * @param propertyNames The names of the properties to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertiesSubqueryExpression - */ - public static Criterion propertiesNotEq(String[] propertyNames, DetachedCriteria dc) { - return new PropertiesSubqueryExpression( propertyNames, "<>", dc ); - } - - /** - * Creates a criterion which checks that the value of multiple given properties as being in to the set of - * values in the subquery result. This form is implicitly using tuple comparisons - * - * @param propertyNames The names of the properties to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertiesSubqueryExpression - */ - public static Criterion propertiesIn(String[] propertyNames, DetachedCriteria dc) { - return new PropertiesSubqueryExpression( propertyNames, "in", dc ); - } - - /** - * Creates a criterion which checks that the value of multiple given properties as being not-in to the set of - * values in the subquery result. This form is implicitly using tuple comparisons - * - * @param propertyNames The names of the properties to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see PropertiesSubqueryExpression - */ - public static Criterion propertiesNotIn(String[] propertyNames, DetachedCriteria dc) { - return new PropertiesSubqueryExpression( propertyNames, "not in", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal equals ALL the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion eqAll(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is greater-than ALL the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion gtAll(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is less-than ALL the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion ltAll(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is greater-than-or-equal-to ALL the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion geAll(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is less-than-or-equal-to ALL the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion leAll(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<=", "all", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is greater-than SOME of the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion gtSome(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is less-than SOME of the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion ltSome(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is greater-than-or-equal-to SOME of the values - * in the subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion geSome(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">=", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is less-than-or-equal-to SOME of the values - * in the subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion leSome(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<=", "some", dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is IN the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion in(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "in", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a literal is NOT IN the values in the - * subquery result. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion notIn(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "not in", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given literal as being equal to the value in - * the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion eq(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "=", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given literal as being not-equal to the value in - * the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion ne(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression(value, "<>", null, dc); - } - - /** - * Creates a criterion which checks that the value of a given literal as being greater-than the value in - * the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion gt(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given literal as being less-than the value in - * the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion lt(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given literal as being greater-than-or-equal-to the - * value in the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion ge(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, ">=", null, dc ); - } - - /** - * Creates a criterion which checks that the value of a given literal as being less-than-or-equal-to the - * value in the subquery result. The implication is that the subquery returns a single result.. - * - * @param value The literal value to use in comparison - * @param dc The detached criteria representing the subquery - * - * @return The Criterion - * - * @see SimpleSubqueryExpression - */ - public static Criterion le(Object value, DetachedCriteria dc) { - return new SimpleSubqueryExpression( value, "<=", null, dc ); - } - - private Subqueries() { - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/criterion/SubqueryExpression.java b/hibernate-core/src/main/java/org/hibernate/criterion/SubqueryExpression.java deleted file mode 100755 index 8cab9a6b30..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/criterion/SubqueryExpression.java +++ /dev/null @@ -1,138 +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 . - */ -package org.hibernate.criterion; - -import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.QueryParameters; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.internal.CriteriaImpl; -import org.hibernate.loader.criteria.CriteriaJoinWalker; -import org.hibernate.loader.criteria.CriteriaQueryTranslator; -import org.hibernate.persister.entity.OuterJoinLoadable; -import org.hibernate.type.Type; - -/** - * A criterion that involves a subquery - * - * @author Gavin King - * @author Steve Ebersole - */ -public abstract class SubqueryExpression implements Criterion { - private CriteriaImpl criteriaImpl; - private String quantifier; - private String op; - private QueryParameters params; - private Type[] types; - private CriteriaQueryTranslator innerQuery; - - protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) { - this.criteriaImpl = dc.getCriteriaImpl(); - this.quantifier = quantifier; - this.op = op; - } - - protected Type[] getTypes() { - return types; - } - - protected abstract String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery); - - @Override - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - final StringBuilder buf = new StringBuilder( toLeftSqlString( criteria, criteriaQuery ) ); - if ( op != null ) { - buf.append( ' ' ).append( op ).append( ' ' ); - } - if ( quantifier != null ) { - buf.append( quantifier ).append( ' ' ); - } - - final SessionFactoryImplementor factory = criteriaQuery.getFactory(); - final OuterJoinLoadable persister = - (OuterJoinLoadable) factory.getMetamodel().entityPersister( criteriaImpl.getEntityOrClassName() ); - - createAndSetInnerQuery( criteriaQuery, factory ); - criteriaImpl.setSession( deriveRootSession( criteria ) ); - - final CriteriaJoinWalker walker = new CriteriaJoinWalker( - persister, - innerQuery, - factory, - criteriaImpl, - criteriaImpl.getEntityOrClassName(), - criteriaImpl.getSession().getLoadQueryInfluencers(), - innerQuery.getRootSQLALias() - ); - - return buf.append( '(' ).append( walker.getSQLString() ).append( ')' ).toString(); - } - - private SharedSessionContractImplementor deriveRootSession(Criteria criteria) { - if ( criteria instanceof CriteriaImpl ) { - return ( (CriteriaImpl) criteria ).getSession(); - } - else if ( criteria instanceof CriteriaImpl.Subcriteria ) { - return deriveRootSession( ( (CriteriaImpl.Subcriteria) criteria ).getParent() ); - } - else { - // could happen for custom Criteria impls. Not likely, but... - // for long term solution, see HHH-3514 - return null; - } - } - - @Override - public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - //the following two lines were added to ensure that this.params is not null, which - //can happen with two-deep nested subqueries - final SessionFactoryImplementor factory = criteriaQuery.getFactory(); - createAndSetInnerQuery( criteriaQuery, factory ); - - final Type[] ppTypes = params.getPositionalParameterTypes(); - final Object[] ppValues = params.getPositionalParameterValues(); - final TypedValue[] tv = new TypedValue[ppTypes.length]; - for ( int i=0; i. - --> - - - - -

- A framework for defining restriction criteria and order criteria. -

- - diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index c67f1fc8b6..951a44776f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -71,7 +71,6 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder; import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport; import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.exception.spi.ConversionContext; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java index 351eaf7ce6..4a36a1c125 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java @@ -25,7 +25,6 @@ import org.hibernate.dialect.function.VarArgsSQLFunction; import org.hibernate.dialect.pagination.AbstractLimitHandler; import org.hibernate.dialect.pagination.LimitHandler; import org.hibernate.dialect.pagination.LimitHelper; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.LockAcquisitionException; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Teradata14Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Teradata14Dialect.java index 9744036649..56b9a9dfda 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Teradata14Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Teradata14Dialect.java @@ -22,7 +22,6 @@ import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.dialect.identity.Teradata14IdentityColumnSupport; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; import org.hibernate.mapping.Column; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java index e160f146d3..14eb776b3b 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/ParameterBinder.java @@ -12,7 +12,6 @@ import java.util.Iterator; import java.util.Map; import org.hibernate.HibernateException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.TypedValue; import org.hibernate.internal.CoreMessageLogger; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/ParameterRecognitionException.java b/hibernate-core/src/main/java/org/hibernate/engine/query/ParameterRecognitionException.java index 3dd434aa06..ca8d156f8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/ParameterRecognitionException.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/ParameterRecognitionException.java @@ -7,11 +7,10 @@ package org.hibernate.engine.query; import org.hibernate.HibernateException; -import org.hibernate.engine.query.spi.ParamLocationRecognizer; +import org.hibernate.query.sql.spi.ParameterRecognizer; /** - * Indicates a problem during parameter recognition via - * {@link ParamLocationRecognizer} + * Indicates a problem during parameter recognition via {@link ParameterRecognizer} * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/internal/NativeQueryInterpreterStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/query/internal/NativeQueryInterpreterStandardImpl.java index 444f043871..c7e133ada2 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/internal/NativeQueryInterpreterStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/internal/NativeQueryInterpreterStandardImpl.java @@ -8,30 +8,25 @@ package org.hibernate.engine.query.internal; import org.hibernate.engine.query.spi.NativeQueryInterpreter; import org.hibernate.engine.query.spi.NativeSQLQueryPlan; -import org.hibernate.engine.query.spi.ParamLocationRecognizer; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.custom.CustomQuery; import org.hibernate.loader.custom.sql.SQLCustomQuery; -import org.hibernate.query.internal.ParameterMetadataImpl; +import org.hibernate.query.sql.internal.ParameterParser; +import org.hibernate.query.sql.spi.ParameterRecognizer; /** * @author Steve Ebersole */ public class NativeQueryInterpreterStandardImpl implements NativeQueryInterpreter { - private final SessionFactoryImplementor sessionFactory; - - public NativeQueryInterpreterStandardImpl(SessionFactoryImplementor sessionFactory) { - this.sessionFactory = sessionFactory; - } + /** + * Singleton access + */ + public static final NativeQueryInterpreterStandardImpl INSTANCE = new NativeQueryInterpreterStandardImpl(); @Override - public ParameterMetadataImpl getParameterMetadata(String nativeQuery) { - final ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( nativeQuery, sessionFactory ); - return new ParameterMetadataImpl( - recognizer.getOrdinalParameterDescriptionMap(), - recognizer.getNamedParameterDescriptionMap() - ); + public void recognizeParameters(String nativeQuery, ParameterRecognizer recognizer) { + ParameterParser.parse( nativeQuery, recognizer ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java index 1ba9dbe6e0..49e496b096 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java @@ -19,7 +19,6 @@ import java.util.Set; import org.hibernate.Filter; import org.hibernate.HibernateException; import org.hibernate.QueryException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeQueryInterpreter.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeQueryInterpreter.java index 0c001bcc6a..12aa6cdcac 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeQueryInterpreter.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeQueryInterpreter.java @@ -6,11 +6,18 @@ */ package org.hibernate.engine.query.spi; +import org.hibernate.Incubating; +import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomQuery; -import org.hibernate.query.internal.ParameterMetadataImpl; +import org.hibernate.query.sql.internal.NativeSelectQueryPlanImpl; +import org.hibernate.query.sql.spi.NativeNonSelectQueryDefinition; +import org.hibernate.query.sql.spi.NativeNonSelectQueryPlan; +import org.hibernate.query.sql.spi.NativeSelectQueryDefinition; +import org.hibernate.query.sql.spi.NativeSelectQueryPlan; +import org.hibernate.query.sql.spi.ParameterRecognizer; import org.hibernate.service.Service; /** @@ -20,38 +27,38 @@ import org.hibernate.service.Service; * @author Gunnar Morling * @author Guillaume Smet */ +@Incubating public interface NativeQueryInterpreter extends Service { /** - * Returns a meta-data object with information about the named and ordinal - * parameters contained in the given native query. + * Parse the given native query and inform the recognizer of all + * recognized parameter markers. * - * @param nativeQuery the native query to analyze. - * - * @return a meta-data object describing the parameters of the given query. - * Must not be {@code null}. + * @param nativeQuery The query to recognize parameters in + * @param recognizer The recognizer to call */ - ParameterMetadataImpl getParameterMetadata(String nativeQuery); + void recognizeParameters(String nativeQuery, ParameterRecognizer recognizer); /** - * Creates a new query plan for the specified native query. - * - * @param specification Describes the query to create a plan for - * @param sessionFactory The current session factory - * - * @return A query plan for the specified native query. + * Creates a new query plan for the passed native query definition */ - NativeSQLQueryPlan createQueryPlan(NativeSQLQuerySpecification specification, SessionFactoryImplementor sessionFactory); + default NativeSelectQueryPlan createQueryPlan( + NativeSelectQueryDefinition queryDefinition, + SessionFactoryImplementor sessionFactory) { + return new NativeSelectQueryPlanImpl( + queryDefinition.getSqlString(), + queryDefinition.getAffectedTableNames(), + queryDefinition.getQueryParameterList(), + queryDefinition.getResultSetMapping(), + queryDefinition.getRowTransformer() + ); + } /** - * Creates a {@link CustomLoader} for the given {@link CustomQuery}. - * - * @param customQuery The CustomQuery to create a loader for - * @param sessionFactory The current session factory - * - * @deprecated This method will be removed in 6. + * Creates a new query plan for the passed native query values */ - @Deprecated - default CustomLoader createCustomLoader(CustomQuery customQuery, SessionFactoryImplementor sessionFactory) { - return new CustomLoader( customQuery, sessionFactory ); + default NativeNonSelectQueryPlan createQueryPlan( + NativeNonSelectQueryDefinition queryDefinition, + SessionFactoryImplementor sessionFactory) { + throw new NotYetImplementedFor6Exception( ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java index 50afb8a81f..7ef6a69e5c 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/NativeSQLQueryPlan.java @@ -12,7 +12,6 @@ import java.sql.SQLException; import org.hibernate.HibernateException; import org.hibernate.action.internal.BulkOperationCleanupAction; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.event.spi.EventSource; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java index 7fc93494b8..a1e82c28cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParamLocationRecognizer.java @@ -15,6 +15,8 @@ import java.util.Map; import org.hibernate.engine.query.ParameterRecognitionException; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.query.sql.internal.ParameterParser; +import org.hibernate.query.sql.spi.ParameterRecognizer; /** * Implements a parameter parser recognizer specifically for the purpose @@ -22,7 +24,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; * * @author Steve Ebersole */ -public class ParamLocationRecognizer implements ParameterParser.Recognizer { +public class ParamLocationRecognizer implements ParameterRecognizer { private Map namedParameterDescriptors; private Map ordinalParameterDescriptors; @@ -57,8 +59,7 @@ public class ParamLocationRecognizer implements ParameterParser.Recognizer { return recognizer; } - @Override - public void complete() { + public void validate() { if ( inFlightNamedStateMap != null && ( inFlightOrdinalStateMap != null || inFlightJpaOrdinalStateMap != null ) ) { throw mixedParamStrategy(); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index 66a92a1951..7570b0382f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -8,7 +8,6 @@ package org.hibernate.engine.spi; import java.io.Serializable; import java.sql.Connection; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -23,11 +22,9 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaUpdate; -import javax.persistence.criteria.Selection; import javax.persistence.metamodel.Metamodel; import org.hibernate.CacheMode; -import org.hibernate.Criteria; import org.hibernate.Filter; import org.hibernate.FlushMode; import org.hibernate.HibernateException; @@ -38,9 +35,7 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MultiIdentifierLoadAccess; import org.hibernate.NaturalIdLoadAccess; -import org.hibernate.Query; import org.hibernate.ReplicationMode; -import org.hibernate.ScrollMode; import org.hibernate.Session; import org.hibernate.SessionEventListener; import org.hibernate.SharedSessionBuilder; @@ -61,9 +56,9 @@ import org.hibernate.jdbc.Work; import org.hibernate.loader.custom.CustomQuery; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.procedure.ProcedureCall; -import org.hibernate.query.spi.NativeQueryImplementor; import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.sql.spi.NativeQueryImplementor; import org.hibernate.resource.jdbc.spi.JdbcSessionContext; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.stat.SessionStatistics; @@ -172,15 +167,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.buildLockOptions( lockModeType, properties ); } - @Override - public QueryImplementor createQuery( - String jpaqlString, - Class resultClass, - Selection selection, - QueryOptions queryOptions) { - return delegate.createQuery( jpaqlString,resultClass, selection, queryOptions ); - } - @Override public void initializeCollection(PersistentCollection collection, boolean writing) throws HibernateException { delegate.initializeCollection( collection, writing ); @@ -206,41 +192,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.getFactory(); } - @Override - public List list(String query, QueryParameters queryParameters) throws HibernateException { - return delegate.list( query, queryParameters ); - } - - @Override - public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException { - return delegate.iterate( query, queryParameters ); - } - - @Override - public ScrollableResultsImplementor scroll(String query, QueryParameters queryParameters) throws HibernateException { - return delegate.scroll( query, queryParameters ); - } - - @Override - public ScrollableResultsImplementor scroll(Criteria criteria, ScrollMode scrollMode) { - return delegate.scroll( criteria, scrollMode ); - } - - @Override - public List list(Criteria criteria) { - return delegate.list( criteria ); - } - - @Override - public List listFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException { - return delegate.listFilter( collection, filter, queryParameters ); - } - - @Override - public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException { - return delegate.iterateFilter( collection, filter, queryParameters ); - } - @Override public EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException { return delegate.getEntityPersister( entityName, object ); @@ -561,11 +512,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.getNamedQuery( name ); } - @Override - public NativeQueryImplementor getNamedSQLQuery(String name) { - return delegate.getNamedSQLQuery( name ); - } - @Override public NativeQueryImplementor getNamedNativeQuery(String name) { return delegate.getNamedNativeQuery( name ); @@ -641,6 +587,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.createStoredProcedureQuery( procedureName, resultSetMappings ); } + @Override + public void prepareForQueryExecution(boolean requiresTxn) { + delegate.prepareForQueryExecution( requiresTxn ); + } + @Override public void joinTransaction() { delegate.joinTransaction(); @@ -695,26 +646,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.createStoredProcedureCall( procedureName, resultSetMappings ); } - @Override - public Criteria createCriteria(Class persistentClass) { - return delegate.createCriteria( persistentClass ); - } - - @Override - public Criteria createCriteria(Class persistentClass, String alias) { - return delegate.createCriteria( persistentClass, alias ); - } - - @Override - public Criteria createCriteria(String entityName) { - return delegate.createCriteria( entityName ); - } - - @Override - public Criteria createCriteria(String entityName, String alias) { - return delegate.createCriteria( entityName, alias ); - } - @Override public SharedSessionBuilder sessionWithOptions() { return delegate.sessionWithOptions(); @@ -980,11 +911,6 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.getCurrentLockMode( object ); } - @Override - public Query createFilter(Object collection, String queryString) { - return delegate.createFilter( collection, queryString ); - } - @Override public void clear() { delegate.clear(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java index ac8e6acf3d..e9068a706f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java @@ -20,8 +20,8 @@ import org.hibernate.graph.RootGraph; import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.jpa.spi.HibernateEntityManagerImplementor; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.query.spi.NativeQueryImplementor; import org.hibernate.query.spi.QueryImplementor; +import org.hibernate.query.sql.spi.NativeQueryImplementor; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; @@ -57,6 +57,11 @@ import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; public interface SessionImplementor extends Session, SharedSessionContractImplementor, HibernateEntityManagerImplementor { + @Override + default SessionImplementor getSession() { + return this; + } + @Override SessionFactoryImplementor getSessionFactory(); @@ -98,23 +103,18 @@ public interface SessionImplementor NativeQueryImplementor createNativeQuery(String sqlString); @Override + @SuppressWarnings("unchecked") NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass); @Override NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping); - @Override - NativeQueryImplementor createSQLQuery(String sqlString); - @Override NativeQueryImplementor getNamedNativeQuery(String name); @Override QueryImplementor getNamedQuery(String queryName); - @Override - NativeQueryImplementor getNamedSQLQuery(String name); - @Override QueryImplementor createQuery(CriteriaQuery criteriaQuery); @@ -124,21 +124,6 @@ public interface SessionImplementor @Override QueryImplementor createQuery(CriteriaDelete deleteQuery); - /** - * {@inheritDoc} - * - * @deprecated (since 5.2) - see deprecation note on super - * - * @return The typed query - */ - @Deprecated - @Override - QueryImplementor createQuery( - String jpaqlString, - Class resultClass, - Selection selection, - QueryOptions queryOptions); - /** * @deprecated OperationalContext should cover this overload I believe; Gail? */ diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java index e12a138b85..5a7f05df8a 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java @@ -8,7 +8,6 @@ package org.hibernate.engine.spi; import java.io.Serializable; import java.sql.Connection; -import java.util.Iterator; import java.util.List; import java.util.UUID; import javax.persistence.FlushModeType; @@ -16,11 +15,9 @@ import javax.persistence.TransactionRequiredException; import javax.persistence.criteria.Selection; import org.hibernate.CacheMode; -import org.hibernate.Criteria; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.Interceptor; -import org.hibernate.ScrollMode; import org.hibernate.SharedSessionContract; import org.hibernate.Transaction; import org.hibernate.cache.spi.CacheTransactionSynchronization; @@ -119,6 +116,11 @@ public interface SharedSessionContractImplementor */ UUID getSessionIdentifier(); + @Override + default SharedSessionContractImplementor getSession() { + return this; + } + /** * Checks whether the session is closed. Provided separately from * {@link #isOpen()} as this method does not attempt any JTA synchronization @@ -277,42 +279,6 @@ public interface SharedSessionContractImplementor Object immediateLoad(String entityName, Serializable id) throws HibernateException; - /** - * Execute a find() query - */ - List list(String query, QueryParameters queryParameters) throws HibernateException; - - /** - * Execute an iterate() query - */ - Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException; - - /** - * Execute a scroll() query - */ - ScrollableResultsImplementor scroll(String query, QueryParameters queryParameters) throws HibernateException; - - /** - * Execute a criteria query - */ - ScrollableResultsImplementor scroll(Criteria criteria, ScrollMode scrollMode); - - /** - * Execute a criteria query - */ - List list(Criteria criteria); - - /** - * Execute a filter - */ - List listFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException; - - /** - * Iterate a filter - */ - Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) - throws HibernateException; - /** * Get the EntityPersister for any instance * diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index 943423518b..a52b7b3b7d 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -22,7 +22,6 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaUpdate; import javax.persistence.criteria.Selection; -import org.hibernate.AssertionFailure; import org.hibernate.CacheMode; import org.hibernate.EmptyInterceptor; import org.hibernate.EntityNameResolver; @@ -39,9 +38,6 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.cache.spi.CacheTransactionSynchronization; import org.hibernate.cfg.Environment; import org.hibernate.dialect.Dialect; -import org.hibernate.query.hql.spi.NamedHqlQueryMemento; -import org.hibernate.query.sql.spi.NamedNativeQueryMemento; -import org.hibernate.query.sql.spi.ResultSetMappingDescriptor; import org.hibernate.engine.internal.SessionEventListenerManagerImpl; import org.hibernate.engine.jdbc.LobCreationContext; import org.hibernate.engine.jdbc.LobCreator; @@ -49,15 +45,9 @@ import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.query.spi.HQLQueryPlan; -import org.hibernate.engine.query.spi.NativeSQLQueryPlan; -import org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn; -import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; -import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.ExceptionConverter; -import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionEventListenerManager; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -65,27 +55,31 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.transaction.internal.TransactionImpl; import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.id.uuid.StandardRandomStrategy; +import org.hibernate.internal.util.StringHelper; import org.hibernate.jpa.internal.util.FlushModeTypeHelper; import org.hibernate.jpa.spi.NativeQueryTupleTransformer; import org.hibernate.jpa.spi.TupleBuilderTransformer; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.procedure.ProcedureCall; -import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.procedure.internal.ProcedureCallImpl; -import org.hibernate.query.ParameterMetadata; +import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.query.Query; -import org.hibernate.query.sql.internal.NativeQueryImpl; -import org.hibernate.query.internal.QueryImpl; -import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.query.hql.spi.NamedHqlQueryMemento; +import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryImplementor; +import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.sql.internal.NativeQueryImpl; +import org.hibernate.query.sql.spi.NamedNativeQueryMemento; +import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.query.sql.spi.ResultSetMappingDescriptor; import org.hibernate.query.sqm.internal.QuerySqmImpl; +import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.resource.jdbc.spi.JdbcSessionContext; import org.hibernate.resource.jdbc.spi.StatementInspector; import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; -import org.hibernate.type.Type; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** @@ -605,111 +599,13 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont this.cacheMode = cacheMode; } - protected HQLQueryPlan getQueryPlan(String query, boolean shallow) throws HibernateException { - return getFactory().getQueryInterpretationCache().getHQLQueryPlan( query, shallow, getLoadQueryInfluencers().getEnabledFilters() ); - } - protected NativeSQLQueryPlan getNativeQueryPlan(NativeSQLQuerySpecification spec) throws HibernateException { - return getFactory().getQueryInterpretationCache().getNativeSQLQueryPlan( spec ); - } - - @Override - public QueryImplementor getNamedQuery(String name) { - checkOpen(); - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - // look as HQL/JPQL first - final NamedHqlQueryMemento hqlQueryMemento = factory.getNamedQueryRepository().getHqlQueryMemento( name ); - if ( hqlQueryMemento != null ) { - return hqlQueryMemento.toQuery( this ); - } - - // then as a native query - final NamedNativeQueryMemento nativeQueryMemento = factory.getNamedQueryRepository().getNativeQueryMemento( name ); - if ( nativeQueryMemento != null ) { - return nativeQueryMemento.toQuery( this ); - } - - throw getExceptionConverter().convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); - } - - protected QueryImplementor createQuery(NamedHqlQueryMemento memento) { - //noinspection unchecked - return new QuerySqmImpl( memento, null, this ); - } - - private NativeQueryImplementor createNativeQuery(NamedNativeQueryMemento queryDefinition, boolean isOrdinalParameterZeroBased) { - final ParameterMetadata parameterMetadata = factory.getQueryInterpretationCache().getSQLParameterMetadata( - queryDefinition.getQueryString(), - isOrdinalParameterZeroBased - ); - return getNativeQueryImplementor( queryDefinition, parameterMetadata ); - } - - private NativeQueryImplementor getNativeQueryImplementor( - NamedNativeQueryMemento memento, - ParameterMetadata parameterMetadata) { - final NativeQueryImpl query = new NativeQueryImpl( memento, this, parameterMetadata ); - - initQueryFromNamedDefinition( query, memento ); - applyQuerySettingsAndHints( query ); - - return query; - } - - protected void initQueryFromNamedDefinition(Query query, NamedHqlQueryMementoImpl nqd) { - // todo : cacheable and readonly should be Boolean rather than boolean... - query.setCacheable( nqd.getCacheable() ); - query.setCacheRegion( nqd.getCacheRegion() ); - query.setReadOnly( nqd.getReadOnly() ); - - if ( nqd.getTimeout() != null ) { - query.setTimeout( nqd.getTimeout() ); - } - if ( nqd.getFetchSize() != null ) { - query.setFetchSize( nqd.getFetchSize() ); - } - if ( nqd.getCacheMode() != null ) { - query.setCacheMode( nqd.getCacheMode() ); - } - if ( nqd.getComment() != null ) { - query.setComment( nqd.getComment() ); - } - if ( nqd.getFirstResult() != null ) { - query.setFirstResult( nqd.getFirstResult() ); - } - if ( nqd.getMaxResults() != null ) { - query.setMaxResults( nqd.getMaxResults() ); - } - if ( nqd.getFlushMode() != null ) { - query.setHibernateFlushMode( nqd.getFlushMode() ); - } - } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // dynamic HQL handling @Override public QueryImplementor createQuery(String queryString) { - checkOpen(); - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - try { - final QueryImpl query = new QueryImpl( - this, - getQueryPlan( queryString, false ).getParameterMetadata(), - queryString - ); - query.setComment( queryString ); - applyQuerySettingsAndHints( query ); - return query; - } - catch (RuntimeException e) { - markForRollbackOnly(); - throw getExceptionConverter().convert( e ); - } - } - - protected void applyQuerySettingsAndHints(Query query) { + return createQuery( queryString, null ); } @Override @@ -720,256 +616,40 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont delayedAfterCompletion(); try { - // do the translation - final QueryImplementor query = createQuery( queryString ); - resultClassChecking( resultClass, query ); + final QueryEngine queryEngine = getFactory().getQueryEngine(); + final QueryInterpretationCache interpretationCache = queryEngine.getInterpretationCache(); + final SqmStatement sqm = interpretationCache.resolveSqmStatement( + queryString, + s -> queryEngine.getSemanticQueryProducer().interpret( queryString ) + ); + + final QuerySqmImpl query = new QuerySqmImpl( + queryString, + sqm, + resultClass, + this + ); + + query.setComment( queryString ); + applyQuerySettingsAndHints( query ); + return query; } - catch ( RuntimeException e ) { + catch (RuntimeException e) { + markForRollbackOnly(); throw getExceptionConverter().convert( e ); } } - @SuppressWarnings({"unchecked", "WeakerAccess", "StatementWithEmptyBody"}) - protected void resultClassChecking(Class resultClass, Query hqlQuery) { - // make sure the query is a select -> HHH-7192 - final HQLQueryPlan queryPlan = getFactory().getQueryInterpretationCache().getHQLQueryPlan( - hqlQuery.getQueryString(), - false, - getLoadQueryInfluencers().getEnabledFilters() - ); - if ( queryPlan.getTranslators()[0].isManipulationStatement() ) { - throw new IllegalArgumentException( "Update/delete queries cannot be typed" ); - } - // do some return type validation checking - if ( Object[].class.equals( resultClass ) ) { - // no validation needed - } - else if ( Tuple.class.equals( resultClass ) ) { - TupleBuilderTransformer tupleTransformer = new TupleBuilderTransformer( hqlQuery ); - hqlQuery.setResultTransformer( tupleTransformer ); - } - else { - final Class dynamicInstantiationClass = queryPlan.getDynamicInstantiationResultType(); - if ( dynamicInstantiationClass != null ) { - if ( ! resultClass.isAssignableFrom( dynamicInstantiationClass ) ) { - throw new IllegalArgumentException( - "Mismatch in requested result type [" + resultClass.getName() + - "] and actual result type [" + dynamicInstantiationClass.getName() + "]" - ); - } - } - else if ( queryPlan.getTranslators()[0].getReturnTypes().length == 1 ) { - // if we have only a single return expression, its java type should match with the requested type - final Type queryResultType = queryPlan.getTranslators()[0].getReturnTypes()[0]; - if ( !resultClass.isAssignableFrom( queryResultType.getReturnedClass() ) ) { - throw new IllegalArgumentException( - "Type specified for TypedQuery [" + - resultClass.getName() + - "] is incompatible with query return type [" + - queryResultType.getReturnedClass() + "]" - ); - } - } - else { - throw new IllegalArgumentException( - "Cannot create TypedQuery for query with more than one return using requested result type [" + - resultClass.getName() + "]" - ); - } - } - } - - @Override - public QueryImplementor createNamedQuery(String name) { - return buildQueryFromName( name, null ); - } - - protected QueryImplementor buildQueryFromName(String name, Class resultType) { - checkOpen(); - try { - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - // todo : apply stored setting at the JPA Query level too - - final NamedHqlQueryMemento hqlQueryMemento = getFactory().getQueryEngine().getNamedQueryRepository().getHqlQueryMemento( name ); - if ( hqlQueryMemento != null ) { - return createQuery( hqlQueryMemento, resultType ); - } - - final NamedNativeQueryMemento nativeQueryMemento = getFactory().getQueryEngine().getNamedQueryRepository().getNativeQueryMemento( name ); - if ( nativeQueryMemento != null ) { - return (QueryImplementor) createNativeQuery( nativeQueryMemento, resultType ); - } - - throw getExceptionConverter().convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); - } - catch (RuntimeException e) { - throw !( e instanceof IllegalArgumentException ) ? new IllegalArgumentException( e ) : e; - } - } - - @SuppressWarnings({"WeakerAccess", "unchecked"}) - protected QueryImplementor createQuery(NamedHqlQueryMemento namedQueryDefinition, Class resultType) { - final QueryImplementor query = createQuery( namedQueryDefinition ); - if ( resultType != null ) { - resultClassChecking( resultType, query ); - } - return query; - } - - @SuppressWarnings({"WeakerAccess", "unchecked"}) - protected NativeQueryImplementor createNativeQuery(NamedNativeQueryMemento queryDefinition, Class resultType) { - if ( resultType != null && !Tuple.class.equals( resultType ) ) { - resultClassChecking( resultType, queryDefinition ); - } - - final NativeQueryImpl query = new NativeQueryImpl( - queryDefinition, - this, - factory.getQueryInterpretationCache().getSQLParameterMetadata( queryDefinition.getQueryString(), false ) - ); - if ( Tuple.class.equals( resultType ) ) { - query.setResultTransformer( new NativeQueryTupleTransformer() ); - } - query.setHibernateFlushMode( queryDefinition.getFlushMode() ); - query.setComment( queryDefinition.getComment() != null ? queryDefinition.getComment() : queryDefinition.getName() ); - if ( queryDefinition.getLockOptions() != null ) { - query.setLockOptions( queryDefinition.getLockOptions() ); - } - - initQueryFromNamedDefinition( query, queryDefinition ); - applyQuerySettingsAndHints( query ); - - return query; - } - - @SuppressWarnings({"unchecked", "WeakerAccess"}) - protected void resultClassChecking(Class resultType, NamedNativeQueryMemento namedQueryDefinition) { - final NativeSQLQueryReturn[] queryReturns; - if ( namedQueryDefinition.getQueryReturns() != null ) { - queryReturns = namedQueryDefinition.getQueryReturns(); - } - else if ( namedQueryDefinition.getResultSetRef() != null ) { - final ResultSetMappingDescriptor rsMapping = getFactory().getNamedQueryRepository().getResultSetMappingDefinition( namedQueryDefinition.getResultSetRef() ); - queryReturns = rsMapping.getQueryReturns(); - } - else { - throw new AssertionFailure( "Unsupported named query model. Please report the bug in Hibernate EntityManager"); - } - - if ( queryReturns.length > 1 ) { - throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" ); - } - - final NativeSQLQueryReturn nativeSQLQueryReturn = queryReturns[0]; - - if ( nativeSQLQueryReturn instanceof NativeSQLQueryRootReturn ) { - final Class actualReturnedClass; - final String entityClassName = ( (NativeSQLQueryRootReturn) nativeSQLQueryReturn ).getReturnEntityName(); - try { - actualReturnedClass = fastSessionServices.classLoaderService.classForName( entityClassName ); - } - catch ( ClassLoadingException e ) { - throw new AssertionFailure( - "Unable to load class [" + entityClassName + "] declared on named native query [" + - namedQueryDefinition.getRegistrationName() + "]" - ); - } - if ( !resultType.isAssignableFrom( actualReturnedClass ) ) { - throw buildIncompatibleException( resultType, actualReturnedClass ); - } - } - else if ( nativeSQLQueryReturn instanceof NativeSQLQueryConstructorReturn ) { - final NativeSQLQueryConstructorReturn ctorRtn = (NativeSQLQueryConstructorReturn) nativeSQLQueryReturn; - if ( !resultType.isAssignableFrom( ctorRtn.getTargetClass() ) ) { - throw buildIncompatibleException( resultType, ctorRtn.getTargetClass() ); - } - } - else { - log.debugf( "Skiping unhandled NativeSQLQueryReturn type : " + nativeSQLQueryReturn ); - } - } - - private IllegalArgumentException buildIncompatibleException(Class resultClass, Class actualResultClass) { - return new IllegalArgumentException( - "Type specified for TypedQuery [" + resultClass.getName() + - "] is incompatible with query return type [" + actualResultClass + "]" - ); - } - - @Override - public QueryImplementor createNamedQuery(String name, Class resultClass) { - return buildQueryFromName( name, resultClass ); - } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // dynamic native (SQL) query handling @Override public NativeQueryImplementor createNativeQuery(String sqlString) { return getNativeQueryImplementor( sqlString, false ); } - @Override - public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass) { - checkOpen(); - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - try { - NativeQueryImplementor query = createNativeQuery( sqlString ); - handleNativeQueryResult(query, resultClass); - return query; - } - catch ( RuntimeException he ) { - throw getExceptionConverter().convert( he ); - } - } - - private void handleNativeQueryResult(NativeQueryImplementor query, Class resultClass) { - if ( Tuple.class.equals( resultClass ) ) { - query.setResultTransformer( new NativeQueryTupleTransformer() ); - } - else { - query.addEntity( "alias1", resultClass.getName(), LockMode.READ ); - } - } - - @Override - public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) { - checkOpen(); - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - try { - NativeQueryImplementor query = createNativeQuery( sqlString ); - query.setResultSetMapping( resultSetMapping ); - return query; - } - catch ( RuntimeException he ) { - throw getExceptionConverter().convert( he ); - } - } - - @Override - public NativeQueryImplementor getNamedNativeQuery(String name) { - checkOpen(); - pulseTransactionCoordinator(); - delayedAfterCompletion(); - - final NamedNativeQueryMemento nativeQueryDefinition = factory.getQueryEngine().getNamedQueryRepository().getNativeQueryMemento( name ); - if ( nativeQueryDefinition != null ) { - return createNativeQuery( nativeQueryDefinition, true ); - } - - throw getExceptionConverter().convert( new IllegalArgumentException( "No query defined for that name [" + name + "]" ) ); - } - - @Override - public NativeQueryImplementor createSQLQuery(String queryString) { - return getNativeQueryImplementor( queryString, true ); - } - protected NativeQueryImplementor getNativeQueryImplementor( String queryString, boolean isOrdinalParameterZeroBased) { @@ -978,26 +658,130 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont delayedAfterCompletion(); try { - NativeQueryImpl query = new NativeQueryImpl( - queryString, - false, - this, - getFactory().getQueryInterpretationCache().getSQLParameterMetadata( queryString, isOrdinalParameterZeroBased ) - ); + NativeQueryImpl query = new NativeQueryImpl( queryString, this ); query.setComment( "dynamic native SQL query" ); return query; } - catch ( RuntimeException he ) { + catch (RuntimeException he) { throw getExceptionConverter().convert( he ); } } + @Override + @SuppressWarnings("unchecked") + public NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass) { + checkOpen(); + pulseTransactionCoordinator(); + delayedAfterCompletion(); + + try { + NativeQueryImplementor query = createNativeQuery( sqlString ); + query.addEntity( "alias1", resultClass.getName(), LockMode.READ ); + return query; + } + catch (RuntimeException he) { + throw getExceptionConverter().convert( he ); + } + } @Override - public NativeQueryImplementor getNamedSQLQuery(String name) { - return getNamedNativeQuery( name ); + public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) { + checkOpen(); + pulseTransactionCoordinator(); + delayedAfterCompletion(); + + final NativeQueryImplementor query; + try { + if ( StringHelper.isNotEmpty( resultSetMapping ) ) { + final ResultSetMappingDescriptor resultSetMappingDescriptor = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getResultSetMappingDescriptor( resultSetMapping ); + + if ( resultSetMappingDescriptor == null ) { + throw new HibernateException( "Could not resolve specified result-set mapping name : " + resultSetMapping ); + } + + query = new NativeQueryImpl( sqlString, resultSetMappingDescriptor, this ); + } + else { + query = new NativeQueryImpl( sqlString, this ); + } + } + catch ( RuntimeException he ) { + throw getExceptionConverter().convert( he ); + } + + return query; } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // named query handling + + @Override + public QueryImplementor getNamedQuery(String queryName) { + return buildNamedQuery( queryName, null ); + } + + @Override + public QueryImplementor createNamedQuery(String name) { + return buildNamedQuery( name, null ); + } + + @Override + public QueryImplementor createNamedQuery(String name, Class resultClass) { + return buildNamedQuery( name, resultClass ); + } + + protected QueryImplementor buildNamedQuery(String queryName, Class resultType) { + checkOpen(); + pulseTransactionCoordinator(); + delayedAfterCompletion(); + + // this method can be called for either a named HQL query or a named native query + + // first see if it is a named HQL query + final NamedHqlQueryMemento namedHqlDescriptor = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getHqlQueryMemento( queryName ); + + if ( namedHqlDescriptor != null ) { + return namedHqlDescriptor.toQuery( this, resultType ); + } + + // otherwise, see if it is a named native query + final NamedNativeQueryMemento namedNativeDescriptor = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getNativeQueryMemento( queryName ); + + if ( namedNativeDescriptor != null ) { + return namedNativeDescriptor.toQuery( this, resultType ); + } + + // todo (6.0) : allow this for named stored procedures as well? + // ultimately they are treated as a Query + + throw getExceptionConverter().convert( new IllegalArgumentException( "No query defined for that name [" + queryName + "]" ) ); + } + + protected void applyQuerySettingsAndHints(Query query) { + } + + + @Override + public NativeQueryImplementor getNamedNativeQuery(String queryName) { + final NamedNativeQueryMemento namedNativeDescriptor = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getNativeQueryMemento( queryName ); + + if ( namedNativeDescriptor != null ) { + return namedNativeDescriptor.toQuery( this ); + } + + throw getExceptionConverter().convert( new IllegalArgumentException( "No query defined for that name [" + queryName + "]" ) ); + } + + @Override @SuppressWarnings("UnnecessaryLocalVariable") public ProcedureCall getNamedProcedureCall(String name) { @@ -1014,6 +798,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return procedureCall; } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // dynamic ProcedureCall support + @Override @SuppressWarnings("UnnecessaryLocalVariable") public ProcedureCall createStoredProcedureCall(String procedureName) { diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FetchingScrollableResultsImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/FetchingScrollableResultsImpl.java index 182b80e854..26a5e25dc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/FetchingScrollableResultsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/FetchingScrollableResultsImpl.java @@ -11,7 +11,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import org.hibernate.HibernateException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.hql.internal.HolderInstantiator; import org.hibernate.loader.Loader; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/ScrollableResultsImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/ScrollableResultsImpl.java index 4fa6308fd8..7845a45af5 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/ScrollableResultsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/ScrollableResultsImpl.java @@ -14,9 +14,7 @@ import org.hibernate.HibernateException; import org.hibernate.JDBCException; import org.hibernate.ScrollableResults; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.hql.internal.HolderInstantiator; import org.hibernate.loader.Loader; import org.hibernate.type.Type; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 813f9a49d6..137a6d03cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -21,8 +21,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -31,6 +29,7 @@ import java.util.Set; import java.util.function.Supplier; import javax.persistence.CacheRetrieveMode; import javax.persistence.CacheStoreMode; +import javax.persistence.EntityGraph; import javax.persistence.EntityManager; import javax.persistence.EntityNotFoundException; import javax.persistence.FlushModeType; @@ -40,9 +39,11 @@ import javax.persistence.PessimisticLockScope; import javax.persistence.StoredProcedureQuery; import javax.persistence.TransactionRequiredException; import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaDelete; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.CriteriaUpdate; import org.hibernate.CacheMode; -import org.hibernate.Criteria; import org.hibernate.Filter; import org.hibernate.FlushMode; import org.hibernate.HibernateException; @@ -56,9 +57,7 @@ import org.hibernate.MultiIdentifierLoadAccess; import org.hibernate.NaturalIdLoadAccess; import org.hibernate.ObjectDeletedException; import org.hibernate.ObjectNotFoundException; -import org.hibernate.QueryException; import org.hibernate.ReplicationMode; -import org.hibernate.ScrollMode; import org.hibernate.Session; import org.hibernate.SessionEventListener; import org.hibernate.SessionException; @@ -71,29 +70,23 @@ import org.hibernate.TypeMismatchException; import org.hibernate.UnknownProfileException; import org.hibernate.UnresolvableObjectException; import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.criterion.NaturalIdentifier; import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.NonContextualLobCreator; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; -import org.hibernate.engine.query.spi.FilterQueryPlan; import org.hibernate.engine.query.spi.HQLQueryPlan; import org.hibernate.engine.query.spi.NativeSQLQueryPlan; import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.ActionQueue; -import org.hibernate.engine.spi.CollectionEntry; import org.hibernate.engine.spi.EffectiveEntityGraph; import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.Status; -import org.hibernate.engine.spi.TypedValue; import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.engine.transaction.spi.TransactionObserver; import org.hibernate.event.spi.AutoFlushEvent; @@ -132,9 +125,6 @@ import org.hibernate.graph.GraphSemantic; import org.hibernate.graph.RootGraph; import org.hibernate.graph.internal.RootGraphImpl; import org.hibernate.graph.spi.RootGraphImplementor; -import org.hibernate.hql.spi.QueryTranslator; -import org.hibernate.internal.CriteriaImpl.CriterionEntry; -import org.hibernate.internal.log.DeprecationLogger; import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.Work; import org.hibernate.jdbc.WorkExecutor; @@ -147,28 +137,25 @@ import org.hibernate.jpa.internal.util.FlushModeTypeHelper; import org.hibernate.jpa.internal.util.LockModeTypeHelper; import org.hibernate.jpa.internal.util.LockOptionsHelper; import org.hibernate.jpa.spi.HibernateEntityManagerImplementor; -import org.hibernate.loader.criteria.CriteriaLoader; import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomQuery; import org.hibernate.metamodel.spi.MetamodelImplementor; -import org.hibernate.param.CollectionFilterKeyParameterSpecification; -import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.MultiLoadOptions; -import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.pretty.MessageHelper; import org.hibernate.procedure.ProcedureCall; import org.hibernate.procedure.spi.NamedCallableQueryMemento; -import org.hibernate.query.UnknownSqlResultSetMappingException; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode; import org.hibernate.query.Query; -import org.hibernate.query.criteria.internal.compile.CompilableCriteria; -import org.hibernate.query.criteria.internal.compile.CriteriaCompiler; -import org.hibernate.query.criteria.internal.expression.CompoundSelectionImpl; +import org.hibernate.query.UnknownSqlResultSetMappingException; import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.sqm.internal.QuerySqmImpl; +import org.hibernate.query.sqm.tree.SqmStatement; +import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; +import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.resource.transaction.TransactionRequiredForJoinException; import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl; import org.hibernate.resource.transaction.spi.TransactionCoordinator; @@ -1392,35 +1379,6 @@ public final class SessionImpl doFlush(); } - @Override - public List list(String query, QueryParameters queryParameters) throws HibernateException { - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - queryParameters.validateParameters(); - - HQLQueryPlan plan = queryParameters.getQueryPlan(); - if ( plan == null ) { - plan = getQueryPlan( query, false ); - } - - autoFlushIfRequired( plan.getQuerySpaces() ); - - final List results; - boolean success = false; - - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try { - results = plan.performList( queryParameters, this ); - success = true; - } - finally { - dontFlushFromFind--; - afterOperation( success ); - delayedAfterCompletion(); - } - return results; - } - @Override public int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException { checkOpenOrWaitingForAutoClose(); @@ -1515,66 +1473,6 @@ public final class SessionImpl return result; } - @Override - public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException { - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - queryParameters.validateParameters(); - - HQLQueryPlan plan = queryParameters.getQueryPlan(); - if ( plan == null ) { - plan = getQueryPlan( query, true ); - } - - autoFlushIfRequired( plan.getQuerySpaces() ); - - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try { - return plan.performIterate( queryParameters, this ); - } - finally { - delayedAfterCompletion(); - dontFlushFromFind--; - } - } - - @Override - public ScrollableResultsImplementor scroll(String query, QueryParameters queryParameters) throws HibernateException { - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - - HQLQueryPlan plan = queryParameters.getQueryPlan(); - if ( plan == null ) { - plan = getQueryPlan( query, false ); - } - - autoFlushIfRequired( plan.getQuerySpaces() ); - - dontFlushFromFind++; - try { - return plan.performScroll( queryParameters, this ); - } - finally { - delayedAfterCompletion(); - dontFlushFromFind--; - } - } - - @Override - public org.hibernate.query.Query createFilter(Object collection, String queryString) { - checkOpen(); - pulseTransactionCoordinator(); - CollectionFilterImpl filter = new CollectionFilterImpl( - queryString, - collection, - this, - getFilterQueryPlan( collection, queryString, null, false ).getParameterMetadata() - ); - filter.setComment( queryString ); - delayedAfterCompletion(); - return filter; - } - @Override public Object instantiate(String entityName, Serializable id) throws HibernateException { @@ -1667,297 +1565,6 @@ public final class SessionImpl return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier(); } - private FilterQueryPlan getFilterQueryPlan( - Object collection, - String filter, - QueryParameters parameters, - boolean shallow) throws HibernateException { - if ( collection == null ) { - throw new NullPointerException( "null collection passed to filter" ); - } - - CollectionEntry entry = persistenceContext.getCollectionEntryOrNull( collection ); - final CollectionPersister roleBeforeFlush = ( entry == null ) ? null : entry.getLoadedPersister(); - - FilterQueryPlan plan = null; - final Map enabledFilters = getLoadQueryInfluencers().getEnabledFilters(); - final SessionFactoryImplementor factory = getFactory(); - if ( roleBeforeFlush == null ) { - // if it was previously unreferenced, we need to flush in order to - // get its state into the database in order to execute query - flush(); - entry = persistenceContext.getCollectionEntryOrNull( collection ); - CollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.getLoadedPersister(); - if ( roleAfterFlush == null ) { - throw new QueryException( "The collection was unreferenced" ); - } - plan = factory.getQueryInterpretationCache().getFilterQueryPlan( - filter, - roleAfterFlush.getRole(), - shallow, - enabledFilters - ); - } - else { - // otherwise, we only need to flush if there are in-memory changes - // to the queried tables - plan = factory.getQueryInterpretationCache().getFilterQueryPlan( - filter, - roleBeforeFlush.getRole(), - shallow, - enabledFilters - ); - if ( autoFlushIfRequired( plan.getQuerySpaces() ) ) { - // might need to run a different filter entirely after the flush - // because the collection role may have changed - entry = persistenceContext.getCollectionEntryOrNull( collection ); - CollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.getLoadedPersister(); - if ( roleBeforeFlush != roleAfterFlush ) { - if ( roleAfterFlush == null ) { - throw new QueryException( "The collection was dereferenced" ); - } - plan = factory.getQueryInterpretationCache().getFilterQueryPlan( - filter, - roleAfterFlush.getRole(), - shallow, - enabledFilters - ); - } - } - } - - if ( parameters != null ) { - parameters.getNamedParameters().put( - CollectionFilterKeyParameterSpecification.PARAM_KEY, - new TypedValue( - entry.getLoadedPersister().getKeyType(), - entry.getLoadedKey() - ) - ); - } - - return plan; - } - - @Override - public List listFilter(Object collection, String filter, QueryParameters queryParameters) { - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, false ); - List results = Collections.EMPTY_LIST; - - boolean success = false; - dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called - try { - results = plan.performList( queryParameters, this ); - success = true; - } - finally { - dontFlushFromFind--; - afterOperation( success ); - delayedAfterCompletion(); - } - return results; - } - - @Override - public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) { - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, true ); - Iterator itr = plan.performIterate( queryParameters, this ); - delayedAfterCompletion(); - return itr; - } - - @Override - public Criteria createCriteria(Class persistentClass, String alias) { - DeprecationLogger.DEPRECATION_LOGGER.deprecatedLegacyCriteria(); - checkOpen(); - checkTransactionSynchStatus(); - return new CriteriaImpl( persistentClass.getName(), alias, this ); - } - - @Override - public Criteria createCriteria(String entityName, String alias) { - DeprecationLogger.DEPRECATION_LOGGER.deprecatedLegacyCriteria(); - checkOpen(); - checkTransactionSynchStatus(); - return new CriteriaImpl( entityName, alias, this ); - } - - @Override - public Criteria createCriteria(Class persistentClass) { - DeprecationLogger.DEPRECATION_LOGGER.deprecatedLegacyCriteria(); - checkOpen(); - checkTransactionSynchStatus(); - return new CriteriaImpl( persistentClass.getName(), this ); - } - - @Override - public Criteria createCriteria(String entityName) { - DeprecationLogger.DEPRECATION_LOGGER.deprecatedLegacyCriteria(); - checkOpen(); - checkTransactionSynchStatus(); - return new CriteriaImpl( entityName, this ); - } - - @Override - public ScrollableResultsImplementor scroll(Criteria criteria, ScrollMode scrollMode) { - // TODO: Is this guaranteed to always be CriteriaImpl? - CriteriaImpl criteriaImpl = (CriteriaImpl) criteria; - - checkOpenOrWaitingForAutoClose(); - pulseTransactionCoordinator(); - - String entityName = criteriaImpl.getEntityOrClassName(); - CriteriaLoader loader = new CriteriaLoader( - getOuterJoinLoadable( entityName ), - getFactory(), - criteriaImpl, - entityName, - getLoadQueryInfluencers() - ); - autoFlushIfRequired( loader.getQuerySpaces() ); - dontFlushFromFind++; - try { - return loader.scroll( this, scrollMode ); - } - finally { - delayedAfterCompletion(); - dontFlushFromFind--; - } - } - - @Override - public List list(Criteria criteria) throws HibernateException { - // TODO: Is this guaranteed to always be CriteriaImpl? - CriteriaImpl criteriaImpl = (CriteriaImpl) criteria; - if ( criteriaImpl.getMaxResults() != null && criteriaImpl.getMaxResults() == 0 ) { - return Collections.EMPTY_LIST; - } - - final NaturalIdLoadAccess naturalIdLoadAccess = this.tryNaturalIdLoadAccess( criteriaImpl ); - if ( naturalIdLoadAccess != null ) { - // EARLY EXIT! - return Arrays.asList( naturalIdLoadAccess.load() ); - } - - - checkOpenOrWaitingForAutoClose(); -// checkTransactionSynchStatus(); - - String[] implementors = getFactory().getMetamodel().getImplementors( criteriaImpl.getEntityOrClassName() ); - int size = implementors.length; - - CriteriaLoader[] loaders = new CriteriaLoader[size]; - Set spaces = new HashSet(); - for ( int i = 0; i < size; i++ ) { - - loaders[i] = new CriteriaLoader( - getOuterJoinLoadable( implementors[i] ), - getFactory(), - criteriaImpl, - implementors[i], - getLoadQueryInfluencers() - ); - - spaces.addAll( loaders[i].getQuerySpaces() ); - - } - - autoFlushIfRequired( spaces ); - - List results = Collections.EMPTY_LIST; - dontFlushFromFind++; - boolean success = false; - try { - for ( int i = 0; i < size; i++ ) { - final List currentResults = loaders[i].list( this ); - currentResults.addAll( results ); - results = currentResults; - } - success = true; - } - finally { - dontFlushFromFind--; - afterOperation( success ); - delayedAfterCompletion(); - } - - return results; - } - - /** - * Checks to see if the CriteriaImpl is a naturalId lookup that can be done via - * NaturalIdLoadAccess - * - * @param criteria The criteria to check as a complete natural identifier lookup. - * - * @return A fully configured NaturalIdLoadAccess or null, if null is returned the standard CriteriaImpl execution - * should be performed - */ - private NaturalIdLoadAccess tryNaturalIdLoadAccess(CriteriaImpl criteria) { - // See if the criteria lookup is by naturalId - if ( !criteria.isLookupByNaturalKey() ) { - return null; - } - - final String entityName = criteria.getEntityOrClassName(); - final EntityPersister entityPersister = getFactory().getMetamodel().entityPersister( entityName ); - - // Verify the entity actually has a natural id, needed for legacy support as NaturalIdentifier criteria - // queries did no natural id validation - if ( !entityPersister.hasNaturalIdentifier() ) { - return null; - } - - // Since isLookupByNaturalKey is true there can be only one CriterionEntry and getCriterion() will - // return an instanceof NaturalIdentifier - final CriterionEntry criterionEntry = criteria.iterateExpressionEntries().next(); - final NaturalIdentifier naturalIdentifier = (NaturalIdentifier) criterionEntry.getCriterion(); - - final Map naturalIdValues = naturalIdentifier.getNaturalIdValues(); - final int[] naturalIdentifierProperties = entityPersister.getNaturalIdentifierProperties(); - - // Verify the NaturalIdentifier criterion includes all naturalId properties, first check that the property counts match - if ( naturalIdentifierProperties.length != naturalIdValues.size() ) { - return null; - } - - final String[] propertyNames = entityPersister.getPropertyNames(); - final NaturalIdLoadAccess naturalIdLoader = this.byNaturalId( entityName ); - - // Build NaturalIdLoadAccess and in the process verify all naturalId properties were specified - for ( int naturalIdentifierProperty : naturalIdentifierProperties ) { - final String naturalIdProperty = propertyNames[naturalIdentifierProperty]; - final Object naturalIdValue = naturalIdValues.get( naturalIdProperty ); - - if ( naturalIdValue == null ) { - // A NaturalId property is missing from the critera query, can't use NaturalIdLoadAccess - return null; - } - - naturalIdLoader.using( naturalIdProperty, naturalIdValue ); - } - - // Criteria query contains a valid naturalId, use the new API - log.warn( - "Session.byNaturalId(" + entityName - + ") should be used for naturalId queries instead of Restrictions.naturalId() from a Criteria" - ); - - return naturalIdLoader; - } - - private OuterJoinLoadable getOuterJoinLoadable(String entityName) throws MappingException { - EntityPersister persister = getFactory().getMetamodel().entityPersister( entityName ); - if ( !( persister instanceof OuterJoinLoadable ) ) { - throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName ); - } - return (OuterJoinLoadable) persister; - } - @Override public boolean contains(Object object) { checkOpen(); @@ -2032,6 +1639,7 @@ public final class SessionImpl } try { + //noinspection RedundantClassCall if ( !HibernateProxy.class.isInstance( object ) && persistenceContext.getEntry( object ) == null ) { // check if it is an entity -> if not throw an exception (per JPA) try { @@ -3577,16 +3185,53 @@ public final class SessionImpl return Collections.unmodifiableMap( properties ); } - @Override - protected void initQueryFromNamedDefinition(Query query, NamedHqlQueryMementoImpl namedQueryDefinition) { - super.initQueryFromNamedDefinition( query, namedQueryDefinition ); - if ( namedQueryDefinition.getLockOptions() != null ) { - if ( namedQueryDefinition.getLockOptions().getLockMode() != null ) { - query.setLockMode( - LockModeTypeHelper.getLockModeType( namedQueryDefinition.getLockOptions().getLockMode() ) - ); - } + @Override + public QueryImplementor createQuery(CriteriaQuery criteriaQuery) { + checkOpen(); + + try { + return new QuerySqmImpl<>( + "", + (SqmStatement) criteriaQuery, + criteriaQuery.getResultType(), + this + ); + } + catch ( RuntimeException e ) { + throw exceptionConverter.convert( e ); + } + } + + @Override + public QueryImplementor createQuery(CriteriaUpdate criteriaUpdate) { + checkOpen(); + try { + return new QuerySqmImpl<>( + "", + (SqmUpdateStatement) criteriaUpdate, + null, + this + ); + } + catch ( RuntimeException e ) { + throw exceptionConverter.convert( e ); + } + } + + @Override + public QueryImplementor createQuery(CriteriaDelete criteriaDelete) { + checkOpen(); + try { + return new QuerySqmImpl<>( + "", + (SqmDeleteStatement) criteriaDelete, + null, + this + ); + } + catch ( RuntimeException e ) { + throw exceptionConverter.convert( e ); } } @@ -3594,7 +3239,9 @@ public final class SessionImpl public StoredProcedureQuery createNamedStoredProcedureQuery(String name) { checkOpen(); try { - final NamedCallableQueryMemento memento = getFactory().getNamedQueryRepository().getNamedProcedureCallMemento( name ); + final NamedCallableQueryMemento memento = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getCallableQueryMemento( name ); if ( memento == null ) { throw new IllegalArgumentException( "No @NamedStoredProcedureQuery was found with that name : " + name ); } @@ -3720,21 +3367,20 @@ public final class SessionImpl @Override public RootGraphImplementor createEntityGraph(Class rootType) { checkOpen(); - return new RootGraphImpl( null, getMetamodel().entity( rootType ), getEntityManagerFactory() ); + return new RootGraphImpl( null, getMetamodel().entity( rootType ), getEntityManagerFactory().getJpaMetamodel() ); } @Override public RootGraphImplementor createEntityGraph(String graphName) { checkOpen(); final RootGraphImplementor named = getEntityManagerFactory().findEntityGraphByName( graphName ); - if ( named != null ) { - return named.makeRootGraph( graphName, true ); + if ( named == null ) { + return null; } - return named; + return named.makeRootGraph( graphName, true ); } @Override - @SuppressWarnings("unchecked") public RootGraphImplementor getEntityGraph(String graphName) { checkOpen(); final RootGraphImplementor named = getEntityManagerFactory().findEntityGraphByName( graphName ); @@ -3745,7 +3391,7 @@ public final class SessionImpl } @Override - public List getEntityGraphs(Class entityClass) { + public List> getEntityGraphs(Class entityClass) { checkOpen(); return getEntityManagerFactory().findEntityGraphsByType( entityClass ); } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index 737803dee4..515e74ff70 100755 --- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java @@ -35,7 +35,6 @@ import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.hibernate.id.IdentifierGeneratorHelper; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/UniqueList.java b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/UniqueList.java new file mode 100644 index 0000000000..5ccbcbf75f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/UniqueList.java @@ -0,0 +1,87 @@ +/* + * 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.internal.util.collections; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; + +/** + * A collection of values that is simultaneously a List (ordered) and a Set (unique) + * + * @author Steve Ebersole + */ +@SuppressWarnings({"NullableProblems", "unused", "WeakerAccess"}) +public class UniqueList extends AbstractList implements Set, List { + private final List elements; + + public UniqueList() { + this( new ArrayList<>() ); + } + + public UniqueList(List elements) { + this.elements = elements; + } + + public UniqueList(int size) { + this.elements = CollectionHelper.arrayList( size ); + } + + @Override + public E get(int index) { + return elements.get( index ); + } + + @Override + public void add(int index, E element) { + if ( elements.contains( element ) ) { + return; + } + elements.add( index, element ); + } + + @Override + public int size() { + return elements.size(); + } + + @Override + public Iterator iterator() { + return elements.iterator(); + } + + @Override + public ListIterator listIterator() { + return elements.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return elements.listIterator( index ); + } + + @Override + public Object[] toArray() { + return elements.toArray(); + } + + @Override + @SuppressWarnings("SuspiciousToArrayCall") + public T[] toArray(T[] a) { + return elements.toArray( a ); + } + + @Override + public Spliterator spliterator() { + return Spliterators.spliterator( this, Spliterator.ORDERED ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java index 2bd4e68d5f..2d60b40df9 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java @@ -9,15 +9,10 @@ package org.hibernate.jpa.spi; import java.util.List; import java.util.Map; import javax.persistence.LockModeType; -import javax.persistence.PersistenceException; -import javax.persistence.criteria.Selection; -import org.hibernate.HibernateException; import org.hibernate.LockOptions; -import org.hibernate.StaleStateException; import org.hibernate.ejb.HibernateEntityManager; import org.hibernate.engine.spi.SessionImplementor; -import org.hibernate.query.Query; import org.hibernate.query.criteria.internal.ValueHandlerFactory; import org.hibernate.type.Type; @@ -107,27 +102,4 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage */ Map getNamedParameterExplicitTypes(); } - - /** - * Used during "compiling" a JPA criteria query. - * - * @param jpaqlString The criteria query rendered as a JPA QL string - * @param resultClass The result type (the type expected in the result list) - * @param selection The selection(s) - * @param queryOptions The options to use to build the query. - * @param The query type - * - * @deprecated (since 5.2) this method form is used to construct a "compiled" representation of - * a JPA Criteria query. However it assumes the old yucky implementation of "compilation" that - * converted the Criteria into a HQL/JPQL string. In 6.0 that is re-written from scratch to - * compile to SQM, and so this method would not be needed in 6.0 - * - * @return The typed query - */ - @Deprecated - Query createQuery( - String jpaqlString, - Class resultClass, - Selection selection, - QueryOptions queryOptions); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 09893e754b..2725f76c29 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -56,7 +56,6 @@ import org.hibernate.engine.spi.EntityUniqueKey; import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistentAttributeInterceptable; import org.hibernate.engine.spi.PersistentAttributeInterceptor; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -70,7 +69,6 @@ import org.hibernate.event.spi.PostLoadEvent; import org.hibernate.event.spi.PostLoadEventListener; import org.hibernate.event.spi.PreLoadEvent; import org.hibernate.event.spi.PreLoadEventListener; -import org.hibernate.hql.internal.HolderInstantiator; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.FetchingScrollableResultsImpl; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java index ad1c253991..5605fdc045 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java @@ -18,7 +18,6 @@ import org.hibernate.HibernateException; import org.hibernate.dialect.pagination.LimitHelper; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java index a093cb38fc..6652aec63f 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java @@ -15,7 +15,6 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java index 43af21749e..f0a9c9c357 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java @@ -15,7 +15,6 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/plan/AbstractLoadPlanBasedCollectionInitializer.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/plan/AbstractLoadPlanBasedCollectionInitializer.java index 0ad87217ee..23704ac71c 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/plan/AbstractLoadPlanBasedCollectionInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/plan/AbstractLoadPlanBasedCollectionInitializer.java @@ -13,7 +13,6 @@ import java.sql.SQLException; import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java index 6a8b9e5120..0fe01d5c0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java @@ -22,7 +22,6 @@ import org.hibernate.ScrollMode; import org.hibernate.Session; import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CriteriaImpl; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java index dabdcfee99..fa21887dba 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java @@ -9,12 +9,10 @@ package org.hibernate.loader.criteria; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -29,10 +27,7 @@ import org.hibernate.QueryException; import org.hibernate.criterion.CriteriaQuery; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.EnhancedProjection; -import org.hibernate.criterion.ParameterInfoCollector; import org.hibernate.criterion.Projection; -import org.hibernate.engine.query.spi.OrdinalParameterDescriptor; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java index cdde43aa9e..a523032111 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java @@ -23,7 +23,6 @@ import org.hibernate.Session; import org.hibernate.cache.spi.QueryKey; import org.hibernate.cache.spi.QueryResultsCache; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.hql.internal.HolderInstantiator; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/NamedParamBinder.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/NamedParamBinder.java index 6961542283..d900f86247 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/NamedParamBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/NamedParamBinder.java @@ -9,7 +9,6 @@ package org.hibernate.loader.custom.sql; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; import org.hibernate.param.ParameterBinder; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/PositionalParamBinder.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/PositionalParamBinder.java index f3eb23edca..664eef81af 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/PositionalParamBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/PositionalParamBinder.java @@ -9,7 +9,6 @@ package org.hibernate.loader.custom.sql; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; import org.hibernate.param.ParameterBinder; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java index 823753360c..df99b915f6 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java @@ -13,11 +13,12 @@ import java.util.Map; import java.util.regex.Pattern; import org.hibernate.QueryException; -import org.hibernate.engine.query.spi.ParameterParser; +import org.hibernate.query.sql.internal.ParameterParser; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.param.ParameterBinder; import org.hibernate.persister.collection.SQLLoadableCollection; import org.hibernate.persister.entity.SQLLoadable; +import org.hibernate.query.sql.spi.ParameterRecognizer; /** * @author Gavin King @@ -289,7 +290,7 @@ public class SQLQueryParser { return recognizer.result.toString(); } - public static class ParameterSubstitutionRecognizer implements ParameterParser.Recognizer { + public static class ParameterSubstitutionRecognizer implements ParameterRecognizer { StringBuilder result = new StringBuilder(); int jdbcPositionalParamCount; @@ -348,9 +349,5 @@ public class SQLQueryParser { public List getParameterValueBinders() { return paramValueBinders; } - - @Override - public void complete() { - } } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java index 85519412d8..3f3929eb46 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java @@ -9,17 +9,14 @@ package org.hibernate.loader.entity; import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Collections; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.LockOptions; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.OuterJoinLoader; -import org.hibernate.param.ParameterBinder; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.Type; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java index fd4573d85a..02e45e2fe5 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java @@ -13,7 +13,6 @@ import java.util.List; import org.hibernate.LockOptions; import org.hibernate.engine.internal.BatchFetchQueueHelper; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.Loader; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java index 7f1c91df2e..32a045d677 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java @@ -25,7 +25,6 @@ import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java index 4944779dca..908cc36eff 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java @@ -16,7 +16,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockOptions; import org.hibernate.engine.spi.EffectiveEntityGraph; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.graph.GraphSemantic; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/BatchingEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/BatchingEntityLoader.java index 2aaa1842b7..8ee422bbd3 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/BatchingEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/BatchingEntityLoader.java @@ -12,7 +12,6 @@ import java.util.Arrays; import java.util.List; import org.hibernate.LockOptions; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.Loader; import org.hibernate.loader.entity.UniqueEntityLoader; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java index eb2f93b67a..4fde09df34 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java @@ -22,7 +22,6 @@ import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.QueryException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.event.spi.EventSource; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader.java index eb320df4c7..e94974b2b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader.java @@ -28,7 +28,6 @@ import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.ResultSetWrapper; import org.hibernate.engine.spi.PersistenceContext; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorHelper.java index ec4576dede..8954c8a169 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorHelper.java @@ -11,7 +11,6 @@ import java.util.HashMap; import java.util.Map; import org.hibernate.engine.spi.EntityKey; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessingContext.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessingContext.java index fa16cca2bd..5f205fbb81 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessingContext.java @@ -8,7 +8,6 @@ package org.hibernate.loader.plan.exec.process.spi; import org.hibernate.LockMode; import org.hibernate.engine.spi.EntityKey; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.plan.exec.spi.LockModeResolver; import org.hibernate.loader.plan.spi.EntityReference; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessor.java index b18219858b..3aae24b8cb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessor.java @@ -10,7 +10,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.spi.AfterLoadAction; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ScrollableResultSetProcessor.java b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ScrollableResultSetProcessor.java index a594c576f4..db38cf98f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ScrollableResultSetProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/plan/exec/process/spi/ScrollableResultSetProcessor.java @@ -8,7 +8,6 @@ package org.hibernate.loader.plan.exec.process.spi; import java.sql.ResultSet; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/NamedEnumValueConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/NamedEnumValueConverter.java index 7776b2eb2c..c43db7e138 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/NamedEnumValueConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/NamedEnumValueConverter.java @@ -19,9 +19,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.model.convert.spi.EnumValueConverter; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; +import org.hibernate.type.descriptor.java.BasicJavaDescriptor; import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; -import org.hibernate.type.descriptor.java.StringTypeDescriptor; -import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** * BasicValueConverter handling the conversion of an enum based on @@ -30,27 +31,43 @@ import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; * @author Steve Ebersole */ public class NamedEnumValueConverter implements EnumValueConverter, Serializable { + private final EnumJavaTypeDescriptor domainTypeDescriptor; + private final SqlTypeDescriptor sqlTypeDescriptor; + private final BasicJavaDescriptor relationalTypeDescriptor; - private final EnumJavaTypeDescriptor enumJavaDescriptor; - - private transient ValueExtractor valueExtractor; - + private transient ValueExtractor valueExtractor; private transient ValueBinder valueBinder; - public NamedEnumValueConverter(EnumJavaTypeDescriptor enumJavaDescriptor) { - this.enumJavaDescriptor = enumJavaDescriptor; - this.valueExtractor = createValueExtractor( enumJavaDescriptor ); - this.valueBinder = createValueBinder(); + public NamedEnumValueConverter( + EnumJavaTypeDescriptor domainTypeDescriptor, + SqlTypeDescriptor sqlTypeDescriptor, + BasicJavaDescriptor relationalTypeDescriptor) { + this.domainTypeDescriptor = domainTypeDescriptor; + this.sqlTypeDescriptor = sqlTypeDescriptor; + this.relationalTypeDescriptor = relationalTypeDescriptor; + + this.valueExtractor = sqlTypeDescriptor.getExtractor( relationalTypeDescriptor ); + this.valueBinder = sqlTypeDescriptor.getBinder( relationalTypeDescriptor ); + } + + @Override + public EnumJavaTypeDescriptor getDomainJavaDescriptor() { + return domainTypeDescriptor; + } + + @Override + public JavaTypeDescriptor getRelationalJavaDescriptor() { + return relationalTypeDescriptor; } @Override public E toDomainValue(String relationalForm) { - return enumJavaDescriptor.fromName( relationalForm ); + return domainTypeDescriptor.fromName( relationalForm ); } @Override public String toRelationalValue(E domainForm) { - return enumJavaDescriptor.toName( domainForm ); + return domainTypeDescriptor.toName( domainForm ); } @Override @@ -58,21 +75,15 @@ public class NamedEnumValueConverter implements EnumValueConvert return Types.VARCHAR; } - @Override - public EnumJavaTypeDescriptor getJavaDescriptor() { - return enumJavaDescriptor; - } @Override public E readValue(ResultSet resultSet, String name, SharedSessionContractImplementor session) throws SQLException { - return valueExtractor.extract( resultSet, name, session ); + return toDomainValue( valueExtractor.extract( resultSet, name, session ) ); } @Override public void writeValue(PreparedStatement statement, E value, int position, SharedSessionContractImplementor session) throws SQLException { - final String jdbcValue = value == null ? null : toRelationalValue( value ); - - valueBinder.bind( statement, jdbcValue, position, session ); + valueBinder.bind( statement, toRelationalValue( value ), position, session ); } @Override @@ -81,18 +92,10 @@ public class NamedEnumValueConverter implements EnumValueConvert return String.format( Locale.ROOT, "'%s'", ( (E) value ).name() ); } - private static ValueExtractor createValueExtractor(EnumJavaTypeDescriptor enumJavaDescriptor) { - return VarcharTypeDescriptor.INSTANCE.getExtractor( enumJavaDescriptor ); - } - - private static ValueBinder createValueBinder() { - return VarcharTypeDescriptor.INSTANCE.getBinder( StringTypeDescriptor.INSTANCE ); - } - private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException { stream.defaultReadObject(); - this.valueExtractor = createValueExtractor( enumJavaDescriptor ); - this.valueBinder = createValueBinder(); + this.valueExtractor = sqlTypeDescriptor.getExtractor( relationalTypeDescriptor ); + this.valueBinder = sqlTypeDescriptor.getBinder( relationalTypeDescriptor ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/OrdinalEnumValueConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/OrdinalEnumValueConverter.java index 0a4c00489d..b1d14d3742 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/OrdinalEnumValueConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/OrdinalEnumValueConverter.java @@ -18,8 +18,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.model.convert.spi.EnumValueConverter; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; +import org.hibernate.type.descriptor.java.BasicJavaDescriptor; import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; -import org.hibernate.type.descriptor.sql.IntegerTypeDescriptor; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** * BasicValueConverter handling the conversion of an enum based on @@ -30,15 +32,22 @@ import org.hibernate.type.descriptor.sql.IntegerTypeDescriptor; public class OrdinalEnumValueConverter implements EnumValueConverter, Serializable { private final EnumJavaTypeDescriptor enumJavaDescriptor; + private final SqlTypeDescriptor sqlTypeDescriptor; + private final BasicJavaDescriptor relationalJavaDescriptor; - private transient ValueExtractor valueExtractor; - + private transient ValueExtractor valueExtractor; private transient ValueBinder valueBinder; - public OrdinalEnumValueConverter(EnumJavaTypeDescriptor enumJavaDescriptor) { + public OrdinalEnumValueConverter( + EnumJavaTypeDescriptor enumJavaDescriptor, + SqlTypeDescriptor sqlTypeDescriptor, + BasicJavaDescriptor relationalJavaDescriptor) { this.enumJavaDescriptor = enumJavaDescriptor; - this.valueExtractor = createValueExtractor( enumJavaDescriptor ); - this.valueBinder = createValueBinder(); + this.sqlTypeDescriptor = sqlTypeDescriptor; + this.relationalJavaDescriptor = relationalJavaDescriptor; + + this.valueExtractor = sqlTypeDescriptor.getExtractor( relationalJavaDescriptor ); + this.valueBinder = sqlTypeDescriptor.getBinder( relationalJavaDescriptor ); } @Override @@ -57,20 +66,23 @@ public class OrdinalEnumValueConverter implements EnumValueConve } @Override - public EnumJavaTypeDescriptor getJavaDescriptor() { + public EnumJavaTypeDescriptor getDomainJavaDescriptor() { return enumJavaDescriptor; } + @Override + public JavaTypeDescriptor getRelationalJavaDescriptor() { + return relationalJavaDescriptor; + } + @Override public E readValue(ResultSet resultSet, String name, SharedSessionContractImplementor session) throws SQLException { - return valueExtractor.extract( resultSet, name, session ); + return toDomainValue( valueExtractor.extract( resultSet, name, session ) ); } @Override public void writeValue(PreparedStatement statement, E value, int position, SharedSessionContractImplementor session) throws SQLException { - final Integer jdbcValue = value == null ? null : toRelationalValue( value ); - - valueBinder.bind( statement, jdbcValue, position, session ); + valueBinder.bind( statement, toRelationalValue( value ), position, session ); } @Override @@ -79,18 +91,10 @@ public class OrdinalEnumValueConverter implements EnumValueConve return Integer.toString( ( (E) value ).ordinal() ); } - private static ValueExtractor createValueExtractor(EnumJavaTypeDescriptor enumJavaDescriptor) { - return IntegerTypeDescriptor.INSTANCE.getExtractor( enumJavaDescriptor ); - } - - private static ValueBinder createValueBinder() { - return IntegerTypeDescriptor.INSTANCE.getBinder( org.hibernate.type.descriptor.java.IntegerTypeDescriptor.INSTANCE ); - } - private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException { stream.defaultReadObject(); - this.valueExtractor = createValueExtractor( enumJavaDescriptor ); - this.valueBinder = createValueBinder(); + this.valueExtractor = sqlTypeDescriptor.getExtractor( relationalJavaDescriptor ); + this.valueBinder = sqlTypeDescriptor.getBinder( relationalJavaDescriptor ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/BasicValueConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/BasicValueConverter.java index c27ed2f85d..3111e2224f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/BasicValueConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/BasicValueConverter.java @@ -6,6 +6,9 @@ */ package org.hibernate.metamodel.model.convert.spi; +import org.hibernate.Incubating; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + /** * Support for basic-value conversions. * @@ -20,6 +23,7 @@ package org.hibernate.metamodel.model.convert.spi; * * @author Steve Ebersole */ +@Incubating public interface BasicValueConverter { /** * Convert the relational form just retrieved from JDBC ResultSet into @@ -32,4 +36,14 @@ public interface BasicValueConverter { * storage into JDBC */ R toRelationalValue(O domainForm); + + /** + * Descriptor for the Java type for the domain portion of this converter + */ + JavaTypeDescriptor getDomainJavaDescriptor(); + + /** + * Descriptor for the Java type for the relational portion of this converter + */ + JavaTypeDescriptor getRelationalJavaDescriptor(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/EnumValueConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/EnumValueConverter.java index 548de76413..b7d895757f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/EnumValueConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/EnumValueConverter.java @@ -19,7 +19,9 @@ import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; * @author Steve Ebersole */ public interface EnumValueConverter extends BasicValueConverter { - EnumJavaTypeDescriptor getJavaDescriptor(); + @Override + EnumJavaTypeDescriptor getDomainJavaDescriptor(); + int getJdbcTypeCode(); O readValue(ResultSet resultSet, String name, SharedSessionContractImplementor session) throws SQLException; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableOutputParameterType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableOutputParameterType.java index a8089783cb..86c3ae6efc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableOutputParameterType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableOutputParameterType.java @@ -10,6 +10,7 @@ import java.sql.CallableStatement; import java.sql.SQLException; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** @@ -34,6 +35,7 @@ public interface AllowableOutputParameterType extends AllowableParameterType< */ SqlTypeDescriptor getSqlTypeDescriptor(); + ValueBinder getValueBinder(); /** diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableParameterType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableParameterType.java index eac00d5d4a..3bf32cd2e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableParameterType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/AllowableParameterType.java @@ -6,10 +6,13 @@ */ package org.hibernate.metamodel.model.domain; +import org.hibernate.type.descriptor.ValueExtractor; + /** * Specialization of DomainType for types that can be used as query parameter bind values * * @author Steve Ebersole */ public interface AllowableParameterType extends SimpleDomainType { + ValueExtractor getValueExtractor(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java index a556f38f51..e435fbe5b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/BasicSqmPathSource.java @@ -8,6 +8,7 @@ package org.hibernate.metamodel.model.domain.internal; import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.query.NavigablePath; +import org.hibernate.query.sqm.IllegalPathUsageException; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.produce.spi.SqmCreationState; @@ -35,7 +36,7 @@ public class BasicSqmPathSource extends AbstractSqmPathSource { @Override public SqmPathSource findSubPathSource(String name) { - throw new IllegalArgumentException( "Basic paths cannot be dereferenced" ); + throw new IllegalPathUsageException( "Basic paths cannot be dereferenced" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java index b03f3da5ce..4f33712a2f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/EntityTypeImpl.java @@ -86,11 +86,6 @@ public class EntityTypeImpl return getJavaType(); } - @Override - public JavaTypeDescriptor getExpressableJavaTypeDescriptor() { - return null; - } - @Override public PersistenceType getPersistenceType() { return PersistenceType.ENTITY; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/package-info.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/package-info.java new file mode 100644 index 0000000000..9b9a84a3b4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/package-info.java @@ -0,0 +1,15 @@ +/* + * 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 + */ + +/** + * Hibernate's run-time mapping model + * + * @implNote At the moment, most of this mapping model is defined in the + * {@link org.hibernate.persister} package. The intention is to move + * all run-time mapping model contracts here. + */ +package org.hibernate.metamodel.model.mapping; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ModelPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ModelPart.java new file mode 100644 index 0000000000..2ff115cd02 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ModelPart.java @@ -0,0 +1,36 @@ +/* + * 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.metamodel.model.mapping.spi; + +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.query.NavigablePath; +import org.hibernate.query.sqm.tree.domain.SqmPath; +import org.hibernate.sql.results.spi.DomainResult; +import org.hibernate.sql.results.spi.DomainResultCreationState; +import org.hibernate.sql.results.spi.DomainResultProducer; + +/** + * Describes a mapping of related to any part of the app's domain model - e.g. + * an attribute, an entity identifier, collection elements, etc + * + * @author Steve Ebersole + */ +public interface ModelPart { + /** + * Create a QueryResult for a specific reference to this ModelPart. + * + * Ultimately this is called from the {@link SqmPath} implementation of + * {@link DomainResultProducer} + */ + default DomainResult createDomainResult( + NavigablePath navigablePath, + int valuesArrayPosition, + String resultVariable, + DomainResultCreationState creationState) { + throw new NotYetImplementedFor6Exception( getClass() ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMapping.java new file mode 100644 index 0000000000..caac55c1ca --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMapping.java @@ -0,0 +1,52 @@ +/* + * 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.metamodel.model.mapping.spi; + +import java.util.Locale; + +import org.hibernate.type.Type; + +/** + * Describes a mapping related to any part of the app's domain model - e.g. + * an attribute, an entity identifier, collection elements, etc + * + * NOTE : this does not include EntityPersister, which however is a ValueMappingContainer + * + * Used in generation of SQL AST + * + * @author Steve Ebersole + */ +public interface ValueMapping { + + /** + * Get the Type associated with this mapping + */ + Type getValueType(); + + /** + * Treat operation. Asks the ValueMapping to treat itself as the + * given `targetType`, if it can. + * + * @apiNote This is not necessarily limited to things the ValueMapping + * itself implements. + */ + default X as(Class targetType) { + if ( targetType.isInstance( this ) ) { + //noinspection unchecked + return (X) this; + } + + throw new IllegalArgumentException( + String.format( + Locale.ROOT, + "`%s` cannot be treated as `%s`", + getClass().getName(), + targetType.getName() + ) + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMappingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMappingContainer.java new file mode 100644 index 0000000000..0bfb97b26c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/mapping/spi/ValueMappingContainer.java @@ -0,0 +1,26 @@ +/* + * 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.metamodel.model.mapping.spi; + +import java.util.function.Consumer; + +/** + * Container for ValueMappings + * + * @author Steve Ebersole + */ +public interface ValueMappingContainer { + /** + * Find a sub-ValueMapping by name + */ + ValueMapping findValueMapping(String name); + + /** + * Visit all of this container's sub-ValueMappings + */ + void visitValueMappings(Consumer consumer); +} diff --git a/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java index 2d7642480e..07ebb786b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java @@ -6,12 +6,9 @@ */ package org.hibernate.param; -import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.QueryException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.Type; diff --git a/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java index def45bdf99..90af89c14c 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java @@ -11,7 +11,6 @@ import java.sql.SQLException; import java.util.Collection; import java.util.Iterator; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.Type; diff --git a/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java index b1123b5297..ebe703b7f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java @@ -9,7 +9,6 @@ package org.hibernate.param; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/param/ParameterBinder.java b/hibernate-core/src/main/java/org/hibernate/param/ParameterBinder.java index 6a88b02fe8..00ddcbf680 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/ParameterBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/param/ParameterBinder.java @@ -9,7 +9,6 @@ package org.hibernate.param; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; /** diff --git a/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java index 178fb5c5f3..8659e8874e 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java @@ -9,7 +9,6 @@ package org.hibernate.param; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java index 669b1eb1f5..77997de0fa 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java @@ -9,7 +9,6 @@ package org.hibernate.param; import java.sql.PreparedStatement; import java.sql.SQLException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.Type; import org.hibernate.type.VersionType; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/SqlExpressableType.java b/hibernate-core/src/main/java/org/hibernate/persister/SqlExpressableType.java index 48bd04d7fd..ac58807288 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/SqlExpressableType.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/SqlExpressableType.java @@ -6,9 +6,38 @@ */ package org.hibernate.persister; +import org.hibernate.sql.exec.spi.JdbcValueBinder; +import org.hibernate.sql.exec.spi.JdbcValueExtractor; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; + /** + * Models the type of a thing that can be used as an expression in a SQL query + * * @author Steve Ebersole */ public interface SqlExpressableType { - // todo (6.0) : define this contract (what should it expose?)- see PropertyMapping + /** + * The descriptor for the Java type represented by this + * expressable type + */ + JavaTypeDescriptor getJavaTypeDescriptor(); + + /** + * The descriptor for the SQL type represented by this + * expressable type + */ + SqlTypeDescriptor getSqlTypeDescriptor(); + + /** + * The strategy for extracting values of this expressable + * type from JDBC ResultSets, CallableStatements, etc + */ + JdbcValueExtractor getJdbcValueExtractor(); + + /** + * The strategy for binding values of this expressable + * type to JDBC PreparedStatements, CallableStatements, etc + */ + JdbcValueBinder getJdbcValueBinder(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 7fea63ab50..445ec2f560 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -24,6 +24,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; @@ -112,6 +113,7 @@ import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.metadata.ClassMetadata; import org.hibernate.metamodel.model.domain.NavigableRole; +import org.hibernate.metamodel.model.mapping.spi.ValueMapping; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper; @@ -1050,6 +1052,22 @@ public abstract class AbstractEntityPersister return result; } + @Override + public ValueMapping findValueMapping(String name) { + for ( AttributeDefinition attributeDefinition : attributeDefinitions ) { + if ( attributeDefinition.getName().equals( name ) ) { + return attributeDefinition; + } + } + + return null; + } + + @Override + public void visitValueMappings(Consumer consumer) { + attributeDefinitions.forEach( consumer ); + } + public Object initializeLazyProperty(String fieldName, Object entity, SharedSessionContractImplementor session) { final PersistenceContext persistenceContext = session.getPersistenceContextInternal(); final EntityEntry entry = persistenceContext.getEntry( entity ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java index 82a660b1c0..10763bd7f1 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java @@ -25,7 +25,7 @@ import org.hibernate.type.Type; * of how Hibernate originally understood composites (embeddables) internally. That is in the process of changing * as Hibernate has added {@link org.hibernate.loader.plan.build.internal.spaces.CompositePropertyMapping} * - * todo (6.0) : move to {@link org.hibernate.persister.spi} - that is its more logic home. AFAIK this + * todo (6.0) : move to {@link org.hibernate.persister.spi} - that is its more logical home. AFAIK this * has never been documented as a public API * * todo (6.0) : re-word these Javadocs @@ -36,7 +36,9 @@ import org.hibernate.type.Type; public interface PropertyMapping { /** - * @asciidoc Resolve a sub-reference relative to this PropertyMapping. E.g., + * @asciidoc + * + * Resolve a sub-reference relative to this PropertyMapping. E.g., * given the PropertyMapping for an entity named `Person` with an embedded * property `#name` calling this method with `"name"` returns the * PropertyMapping for the `Name` embeddable diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/package-info.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/package-info.java new file mode 100644 index 0000000000..379746c599 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/package-info.java @@ -0,0 +1,11 @@ +/* + * 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 + */ + +/** + * Contracts used in walking a persister tree + */ +package org.hibernate.persister.walking; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java index 4a87990f78..bfc0ba5a5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java @@ -20,25 +20,25 @@ public interface AssociationAttributeDefinition extends AttributeDefinition { @Override AssociationType getType(); - public AssociationKey getAssociationKey(); + AssociationKey getAssociationKey(); - public static enum AssociationNature { + enum AssociationNature { ANY, ENTITY, COLLECTION } - public AssociationNature getAssociationNature(); + AssociationNature getAssociationNature(); - public EntityDefinition toEntityDefinition(); + EntityDefinition toEntityDefinition(); - public CollectionDefinition toCollectionDefinition(); + CollectionDefinition toCollectionDefinition(); - public AnyMappingDefinition toAnyDefinition(); + AnyMappingDefinition toAnyDefinition(); - public FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath); + FetchStrategy determineFetchPlan(LoadQueryInfluencers loadQueryInfluencers, PropertyPath propertyPath); - public CascadeStyle determineCascadeStyle(); + CascadeStyle determineCascadeStyle(); - public HydratedCompoundValueHandler getHydratedCompoundValueExtractor(); + HydratedCompoundValueHandler getHydratedCompoundValueExtractor(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java index 80b5b6e301..dad5dd052f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeDefinition.java @@ -6,14 +6,16 @@ */ package org.hibernate.persister.walking.spi; +import org.hibernate.metamodel.model.mapping.spi.ValueMapping; import org.hibernate.type.Type; /** + * Descriptor for * @author Steve Ebersole */ -public interface AttributeDefinition { - public AttributeSource getSource(); - public String getName(); - public Type getType(); - public boolean isNullable(); +public interface AttributeDefinition extends ValueMapping { + AttributeSource getSource(); + String getName(); + Type getType(); + boolean isNullable(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java index 93196adb76..c56b10d54d 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/AttributeSource.java @@ -6,9 +6,11 @@ */ package org.hibernate.persister.walking.spi; +import org.hibernate.metamodel.model.mapping.spi.ValueMappingContainer; + /** * @author Steve Ebersole */ -public interface AttributeSource { - public Iterable getAttributes(); +public interface AttributeSource extends ValueMappingContainer { + Iterable getAttributes(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java index 533c1d57de..c80a3a53b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/CollectionDefinition.java @@ -13,9 +13,9 @@ import org.hibernate.type.CollectionType; * @author Steve Ebersole */ public interface CollectionDefinition { - public CollectionPersister getCollectionPersister(); - public CollectionType getCollectionType(); + CollectionPersister getCollectionPersister(); + CollectionType getCollectionType(); - public CollectionIndexDefinition getIndexDefinition(); - public CollectionElementDefinition getElementDefinition(); + CollectionIndexDefinition getIndexDefinition(); + CollectionElementDefinition getElementDefinition(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java index c9f36310ea..e001c9d33c 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java @@ -6,12 +6,14 @@ */ package org.hibernate.persister.walking.spi; +import org.hibernate.metamodel.model.mapping.spi.ValueMapping; + /** * Describes aspects of the identifier for an entity * * @author Steve Ebersole */ -public interface EntityIdentifierDefinition { +public interface EntityIdentifierDefinition extends ValueMapping { /** * Is the entity identifier encapsulated? Meaning, is it represented by a single attribute? * @@ -20,7 +22,7 @@ public interface EntityIdentifierDefinition { * castable to {@link NonEncapsulatedEntityIdentifierDefinition}). * */ - public boolean isEncapsulated(); + boolean isEncapsulated(); - public EntityDefinition getEntityDefinition(); + EntityDefinition getEntityDefinition(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/Query.java b/hibernate-core/src/main/java/org/hibernate/query/Query.java index 3c98076a35..8e211d4435 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/Query.java +++ b/hibernate-core/src/main/java/org/hibernate/query/Query.java @@ -102,25 +102,6 @@ public interface Query extends TypedQuery, CommonQueryContract { return applyGraph( graph, GraphSemantic.LOAD ); } - /** - * Return the query results as an Iterator. If the query - * contains multiple results pre row, the results are returned in - * an instance of Object[].
- *
- * Entities returned as results are initialized on demand. The first - * SQL query returns identifiers only.
- * - * @return the result iterator - * - * @deprecated Deprecated functionality with no real replacement. Use one - * {@link #list} / {@link #getResultList} instead and open Iterator - * on returned List or {@link #stream()} / {@link #getResultStream()} - */ - @Deprecated - default Iterator iterate() { - return list().iterator(); - } - /** * Return the query results as ScrollableResults. The * scrollability of the returned results depends upon JDBC driver diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/NamedHqlQueryMementoImpl.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/NamedHqlQueryMementoImpl.java index 2a6bf22fbf..8540c6837d 100755 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/NamedHqlQueryMementoImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/NamedHqlQueryMementoImpl.java @@ -16,9 +16,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.hql.spi.HqlQueryImplementor; import org.hibernate.query.hql.spi.NamedHqlQueryMemento; import org.hibernate.query.spi.AbstractNamedQueryMemento; -import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.sqm.internal.QuerySqmImpl; -import org.hibernate.type.BasicType; /** * Definition of a named query, defined in the mapping metadata. @@ -121,33 +119,11 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen @Override public HqlQueryImplementor toQuery(SharedSessionContractImplementor session) { - return null; + return toQuery( session, null ); } @Override public HqlQueryImplementor toQuery(SharedSessionContractImplementor session, Class resultType) { - final QuerySqmImpl query = new QuerySqmImpl<>( this, resultType, session ); - - for ( Map.Entry entry : parameterTypes.entrySet() ) { - final BasicType hintedType = session.getFactory() - .getMetamodel() - .getTypeConfiguration() - .getBasicTypeRegistry() - .getRegisteredType( entry.getValue() ); - final QueryParameterImplementor queryParameter = query.getParameterMetadata().getQueryParameter( entry.getKey() ); - queryParameter.applyAnticipatedType( hintedType ); - } - - - if ( firstResult != null ) { - query.setFirstResult( firstResult ); - } - if ( maxResults != null ) { - query.setMaxResults( maxResults ); - } - - applyBaseOptions( query, session ); - - return query; + return new QuerySqmImpl<>( this, resultType, session ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QuerySplitter.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QuerySplitter.java index 508cb229a2..7cef98f76f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QuerySplitter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QuerySplitter.java @@ -15,9 +15,9 @@ import org.hibernate.internal.util.collections.Stack; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.NavigablePath; import org.hibernate.query.sqm.consume.spi.BaseSemanticQueryWalker; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.hql.spi.SqmPathRegistry; -import org.hibernate.query.sqm.produce.SqmQuerySpecCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmQuerySpecCreationProcessingState; import org.hibernate.query.sqm.produce.spi.ImplicitAliasGenerator; import org.hibernate.query.sqm.produce.spi.SqmCreationContext; import org.hibernate.query.sqm.produce.spi.SqmCreationOptions; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartDelayedResolution.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartDelayedResolution.java index 7d7facc5c2..bf6269490e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartDelayedResolution.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartDelayedResolution.java @@ -20,7 +20,7 @@ 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.type.descriptor.java.spi.EnumJavaDescriptor; +import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; /** * A delayed resolution of a non-terminal path part @@ -104,7 +104,7 @@ public class SemanticPathPartDelayedResolution implements SemanticPathPart, Full //noinspection unchecked return new SqmEnumLiteral( enumValue, - (EnumJavaDescriptor) creationContext.getJpaMetamodel() + (EnumJavaTypeDescriptor) creationContext.getJpaMetamodel() .getTypeConfiguration() .getJavaTypeDescriptorRegistry() .resolveDescriptor( referencedClass ), diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartJoinPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartJoinPredicate.java index 1e68e80ac1..681cff63df 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartJoinPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartJoinPredicate.java @@ -11,7 +11,7 @@ import java.util.Locale; import org.hibernate.query.SemanticException; import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.hql.spi.SqmPathRegistry; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.expression.SqmExpression; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartQualifiedJoinPath.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartQualifiedJoinPath.java index 1d9a8c286b..b1977c1685 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartQualifiedJoinPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticPathPartQualifiedJoinPath.java @@ -11,7 +11,7 @@ import org.hibernate.query.SemanticException; import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.hql.spi.SqmPathRegistry; import org.hibernate.query.sqm.SqmJoinable; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.domain.SqmPath; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java index 9e028c0d00..287986c8f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java @@ -48,7 +48,7 @@ import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.StrictJpaComplianceViolation; import org.hibernate.query.sqm.UnknownEntityException; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.produce.SqmTreeCreationLogger; import org.hibernate.query.sqm.produce.function.SqmFunctionTemplate; import org.hibernate.query.sqm.produce.function.spi.NamedSqmFunctionTemplate; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java index f01649b8d5..f788d638e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java @@ -18,7 +18,7 @@ import org.hibernate.query.hql.spi.SqmPathRegistry; import org.hibernate.query.sqm.AliasCollisionException; import org.hibernate.query.sqm.ParsingException; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.produce.SqmTreeCreationLogger; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/SqmPathRegistry.java b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/SqmPathRegistry.java index 9b1cd610e5..6355192c69 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/SqmPathRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/SqmPathRegistry.java @@ -23,14 +23,15 @@ import org.hibernate.query.sqm.tree.select.SqmSelection; */ @Incubating public interface SqmPathRegistry { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // SqmPath + + /** + * Register an SqmPath + */ void register(SqmPath sqmPath); - SqmSelection findSelectionByAlias(String alias); - - SqmSelection findSelectionByPosition(int position); - - void register(SqmSelection selection); - /** * Find a SqmFrom by its identification variable (alias). Will search any * parent contexts as well @@ -69,4 +70,24 @@ public interface SqmPathRegistry { * @return The existing or just-created SqmPath */ SqmPath resolvePath(NavigablePath path, Function creator); + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // SqmSelection + + /** + * Register an SqmSelection + */ + void register(SqmSelection selection); + + /** + * Find an SqmSelection by the explicit alias assigned to it + */ + SqmSelection findSelectionByAlias(String alias); + + /** + * Find an SqmSelection by its position in the SqmSelectClause + */ + SqmSelection findSelectionByPosition(int position); + } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java b/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java index bee9f8b6c1..4167da6c3f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java @@ -50,7 +50,6 @@ import org.hibernate.TypeMismatchException; import org.hibernate.engine.query.spi.EntityGraphQueryHint; import org.hibernate.engine.query.spi.HQLQueryPlan; import org.hibernate.engine.spi.ExceptionConverter; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java index 8a6a003a68..5e319dcc81 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheDisabledImpl.java @@ -8,9 +8,11 @@ package org.hibernate.query.internal; import java.util.function.Function; +import org.hibernate.query.ParameterMetadata; import org.hibernate.query.spi.NonSelectQueryPlan; import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.SelectQueryPlan; +import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sqm.tree.SqmStatement; /** @@ -46,12 +48,10 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation } @Override - public SqmStatement getSqmStatement(String queryString) { - return null; - } - - @Override - public void cacheSqmStatement(String key, SqmStatement sqmStatement) { + public ParameterInterpretation resolveNativeQueryParameters( + String queryString, + Function creator) { + return creator.apply( queryString ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java index 2ff4841ff3..6fb8d76b4b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryInterpretationCacheStandardImpl.java @@ -11,9 +11,10 @@ import java.util.function.Function; import org.hibernate.internal.util.collections.BoundedConcurrentHashMap; import org.hibernate.query.QueryLogger; import org.hibernate.query.spi.NonSelectQueryPlan; -import org.hibernate.query.spi.QueryPlan; import org.hibernate.query.spi.QueryInterpretationCache; +import org.hibernate.query.spi.QueryPlan; import org.hibernate.query.spi.SelectQueryPlan; +import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sqm.tree.SqmStatement; import org.jboss.logging.Logger; @@ -39,13 +40,16 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation * the cache of the actual plans... */ private final BoundedConcurrentHashMap queryPlanCache; + private final BoundedConcurrentHashMap> sqmStatementCache; + private final BoundedConcurrentHashMap nativeQueryParamCache; public QueryInterpretationCacheStandardImpl(int maxQueryPlanCount) { log.debugf( "Starting QueryPlanCache(%s)", maxQueryPlanCount ); queryPlanCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); sqmStatementCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); + nativeQueryParamCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS ); } @Override @@ -76,27 +80,27 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation String queryString, Function> creator) { log.tracef( "QueryPlan#resolveSqmStatement(%s)", queryString ); - SqmStatement sqmStatement = sqmStatementCache.get( queryString ); - if ( sqmStatement == null ) { - log.debugf( "Creating and caching SqmStatement - %s", queryString ); - sqmStatement = creator.apply( queryString ); - sqmStatementCache.put( queryString, sqmStatement ); - } - return sqmStatement; - } - - - @Override - public SqmStatement getSqmStatement(String queryString) { - log.tracef( "#getSqmStatement( %s )", queryString ); - return sqmStatementCache.get( queryString ); + return sqmStatementCache.computeIfAbsent( + queryString, + s -> { + log.debugf( "Creating and caching SqmStatement - %s", queryString ); + return creator.apply( queryString ); + } + ); } @Override - public void cacheSqmStatement(String queryString, SqmStatement sqmStatement) { - log.tracef( "#cacheSqmStatement( %s )", queryString ); - // todo (6.0) : Log and stats, see HHH-12855 - sqmStatementCache.putIfAbsent( queryString, sqmStatement ); + public ParameterInterpretation resolveNativeQueryParameters( + String queryString, + Function creator) { + log.tracef( "QueryPlan#resolveNativeQueryParameters(%s)", queryString ); + return nativeQueryParamCache.computeIfAbsent( + queryString, + s -> { + log.debugf( "Creating and caching SqmStatement - %s", queryString ); + return creator.apply( queryString ); + } + ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterNamedImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterNamedImpl.java index 36dc95e8ea..7f7b4a482d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterNamedImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterNamedImpl.java @@ -4,13 +4,13 @@ * 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.internal; import java.util.Objects; -import org.hibernate.metamodel.model.mapping.spi.AllowableParameterType; -import org.hibernate.query.named.spi.ParameterMemento; +import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.query.AbstractQueryParameter; +import org.hibernate.query.spi.NamedQueryMemento; import org.hibernate.query.sqm.tree.expression.SqmParameter; /** @@ -30,12 +30,10 @@ public class QueryParameterNamedImpl extends AbstractQueryParameter { assert parameter.getName() != null; assert parameter.getPosition() == null; - return new QueryParameterNamedImpl( + return new QueryParameterNamedImpl<>( parameter.getName(), parameter.allowMultiValuedBinding(), - parameter.getAnticipatedType() != null ? - (AllowableParameterType) parameter.getAnticipatedType() : - null + parameter.getAnticipatedType() ); } @@ -53,6 +51,7 @@ public class QueryParameterNamedImpl extends AbstractQueryParameter { String name, boolean allowMultiValuedBinding, AllowableParameterType anticipatedType) { + //noinspection unchecked super( allowMultiValuedBinding, anticipatedType ); this.name = name; } @@ -63,7 +62,7 @@ public class QueryParameterNamedImpl extends AbstractQueryParameter { } @Override - public ParameterMemento toMemento() { + public NamedQueryMemento.ParameterMemento toMemento() { return session -> new QueryParameterNamedImpl( getName(), allowsMultiValuedBinding(), getHibernateType() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterPositionalImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterPositionalImpl.java index b7d809c0ce..ab74f13323 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterPositionalImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterPositionalImpl.java @@ -34,7 +34,7 @@ public class QueryParameterPositionalImpl extends AbstractQueryParameter { assert parameter.getPosition() != null; assert parameter.getName() == null; - return new QueryParameterPositionalImpl( + return new QueryParameterPositionalImpl<>( parameter.getPosition(), parameter.allowMultiValuedBinding(), parameter.getAnticipatedType() diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java index d9679a89b6..7aab1128cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java @@ -90,6 +90,7 @@ import static org.hibernate.jpa.QueryHints.SPEC_HINT_TIMEOUT; /** * @author Steve Ebersole */ +@SuppressWarnings("WeakerAccess") public abstract class AbstractQuery implements QueryImplementor { private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( AbstractQuery.class ); @@ -427,7 +428,6 @@ public abstract class AbstractQuery implements QueryImplementor { } } - @SuppressWarnings("WeakerAccess") protected void putIfNotNull(Map 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 @@ -437,7 +437,6 @@ public abstract class AbstractQuery implements QueryImplementor { } } - @SuppressWarnings("WeakerAccess") protected void putIfNotNull(Map hints, String hintName, Object hintValue) { if ( hintValue != null ) { hints.put( hintName, hintValue ); @@ -507,6 +506,7 @@ public abstract class AbstractQuery implements QueryImplementor { } } else { + //noinspection ConstantConditions applied = false; } } @@ -1243,10 +1243,11 @@ public abstract class AbstractQuery implements QueryImplementor { private FlushMode sessionFlushMode; private CacheMode sessionCacheMode; - @SuppressWarnings("WeakerAccess") - protected void beforeQuery() { + protected void beforeQuery(boolean requiresTxn) { getQueryParameterBindings().validate(); + getSession().prepareForQueryExecution( requiresTxn ); + prepareForExecution(); assert sessionFlushMode == null; @@ -1265,7 +1266,6 @@ public abstract class AbstractQuery implements QueryImplementor { } } - @SuppressWarnings("WeakerAccess") protected void prepareForExecution() { } @@ -1351,7 +1351,7 @@ public abstract class AbstractQuery implements QueryImplementor { @Override public List list() { - beforeQuery(); + beforeQuery( false ); try { return doList(); } @@ -1423,7 +1423,7 @@ public abstract class AbstractQuery implements QueryImplementor { @Override public ScrollableResultsImplementor scroll(ScrollMode scrollMode) { - beforeQuery(); + beforeQuery( false ); try { return doScroll( scrollMode ); } @@ -1454,7 +1454,7 @@ public abstract class AbstractQuery implements QueryImplementor { ) ); } - beforeQuery(); + beforeQuery( true ); try { return doExecuteUpdate(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/ParameterMetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/query/spi/ParameterMetadataImplementor.java index ce1f92f418..f3125aa355 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/ParameterMetadataImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/ParameterMetadataImplementor.java @@ -12,7 +12,6 @@ import javax.persistence.Parameter; import org.hibernate.query.ParameterMetadata; import org.hibernate.query.QueryParameter; -import org.hibernate.procedure.spi.ProcedureParameterImplementor; /** * @author Steve Ebersole @@ -33,11 +32,11 @@ public interface ParameterMetadataImplementor extends ParameterMetadata { boolean hasAnyMatching(Predicate> filter); @Override - ProcedureParameterImplementor getQueryParameter(String name); + QueryParameterImplementor getQueryParameter(String name); @Override - ProcedureParameterImplementor getQueryParameter(int positionLabel); + QueryParameterImplementor getQueryParameter(int positionLabel); @Override - ProcedureParameterImplementor resolve(Parameter param); + QueryParameterImplementor resolve(Parameter param); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java index bce42dc62e..4faf429a6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryInterpretationCache.java @@ -9,6 +9,7 @@ package org.hibernate.query.spi; import java.util.function.Function; import org.hibernate.Incubating; +import org.hibernate.query.sql.spi.ParameterInterpretation; import org.hibernate.query.sqm.tree.SqmStatement; /** @@ -29,8 +30,8 @@ public interface QueryInterpretationCache { void cacheNonSelectQueryPlan(Key key, NonSelectQueryPlan plan); SqmStatement resolveSqmStatement(String queryString, Function> creator); - SqmStatement getSqmStatement(String queryString); - void cacheSqmStatement(String key, SqmStatement sqmStatement); + + ParameterInterpretation resolveNativeQueryParameters(String queryString, Function creator); boolean isEnabled(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java index d8f1664979..5f3611f60f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java @@ -103,7 +103,7 @@ public class NamedNativeQueryMementoImpl extends AbstractNamedQueryMemento imple @Override @SuppressWarnings("unchecked") public NativeQueryImplementor toQuery(SharedSessionContractImplementor session, Class resultType) { - return new NativeQueryImpl( this, session, resultType ); + return new NativeQueryImpl( this, resultType, session ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java new file mode 100644 index 0000000000..b6fff3cc3b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java @@ -0,0 +1,28 @@ +/* + * 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.internal; + +import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.query.spi.NonSelectQueryPlan; +import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.sql.exec.spi.ExecutionContext; + +/** + * @author Steve Ebersole + */ +public class NativeNonSelectQueryPlanImpl implements NonSelectQueryPlan { + private final NativeQueryImplementor nativeQuery; + + public NativeNonSelectQueryPlanImpl(NativeQueryImplementor nativeQuery) { + this.nativeQuery = nativeQuery; + } + + @Override + public int executeUpdate(ExecutionContext executionContext) { + throw new NotYetImplementedException(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index 5bcafd05c4..6c942fc951 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -15,13 +15,18 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; +import java.util.Collections; import java.util.Date; -import java.util.Iterator; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; import javax.persistence.FlushModeType; import javax.persistence.LockModeType; import javax.persistence.Parameter; +import javax.persistence.PersistenceException; import javax.persistence.TemporalType; import org.hibernate.CacheMode; @@ -30,34 +35,55 @@ import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; +import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.QueryException; import org.hibernate.ScrollMode; -import org.hibernate.query.internal.AbstractProducedQuery; -import org.hibernate.query.internal.NativeQueryReturnBuilder; -import org.hibernate.query.internal.NativeQueryReturnBuilderFetchImpl; -import org.hibernate.query.internal.NativeQueryReturnBuilderRootImpl; -import org.hibernate.query.internal.QueryParameterBindingsImpl; -import org.hibernate.query.spi.AbstractQuery; -import org.hibernate.query.spi.NamedResultSetMappingMemento; -import org.hibernate.query.sql.spi.NamedNativeQueryMemento; -import org.hibernate.query.sql.spi.ResultSetMappingDescriptor; -import org.hibernate.engine.query.spi.EntityGraphQueryHint; +import org.hibernate.engine.query.spi.NativeQueryInterpreter; import org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn; -import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; -import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; 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.util.StringHelper; -import org.hibernate.query.NativeQuery; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.metamodel.model.domain.BasicDomainType; +import org.hibernate.query.Limit; import org.hibernate.query.ParameterMetadata; import org.hibernate.query.Query; import org.hibernate.query.QueryParameter; -import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.query.ResultListTransformer; +import org.hibernate.query.TupleTransformer; +import org.hibernate.query.internal.NativeQueryReturnBuilder; +import org.hibernate.query.internal.NativeQueryReturnBuilderFetchImpl; +import org.hibernate.query.internal.NativeQueryReturnBuilderRootImpl; +import org.hibernate.query.internal.ParameterMetadataImpl; +import org.hibernate.query.internal.QueryOptionsImpl; +import org.hibernate.query.internal.QueryParameterBindingsImpl; +import org.hibernate.query.spi.AbstractQuery; +import org.hibernate.query.spi.MutableQueryOptions; +import org.hibernate.query.spi.NonSelectQueryPlan; +import org.hibernate.query.spi.ParameterMetadataImplementor; +import org.hibernate.query.spi.QueryEngine; +import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.QueryParameterBindings; +import org.hibernate.query.spi.QueryParameterImplementor; import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.spi.SelectQueryPlan; +import org.hibernate.query.sql.spi.NamedNativeQueryMemento; +import org.hibernate.query.sql.spi.NativeQueryImplementor; +import org.hibernate.query.sql.spi.NativeSelectQueryDefinition; +import org.hibernate.query.sql.spi.NonSelectInterpretationsKey; +import org.hibernate.query.sql.spi.ParameterInterpretation; +import org.hibernate.query.sql.spi.SelectInterpretationsKey; +import org.hibernate.sql.exec.spi.Callback; +import org.hibernate.sql.exec.spi.DomainParameterBindingContext; +import org.hibernate.sql.exec.spi.ExecutionContext; +import org.hibernate.sql.results.spi.JdbcValuesMappingDescriptor; +import org.hibernate.sql.results.spi.RowTransformer; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.Type; @@ -66,96 +92,102 @@ import static org.hibernate.jpa.QueryHints.HINT_NATIVE_LOCKMODE; /** * @author Steve Ebersole */ -public class NativeQueryImpl extends AbstractQuery implements NativeQueryImplementor { +@SuppressWarnings("WeakerAccess") +public class NativeQueryImpl + extends AbstractQuery + implements NativeQueryImplementor, DomainParameterBindingContext, ExecutionContext { private final String sqlString; - private final QueryParameterBindingsImpl queryParameterBindings; + + private final ParameterMetadataImplementor parameterMetadata; + private final List> occurrenceOrderedParamList; + private final QueryParameterBindings parameterBindings; + + private final QueryOptionsImpl queryOptions = new QueryOptionsImpl(); + + private Set querySpaces; + + + private List queryReturns; private List queryReturnBuilders; private boolean autoDiscoverTypes; - private Collection querySpaces; - - private final LockOptions lockOptions = new LockOptions(); private Serializable collectionKey; /** * Constructs a NativeQueryImpl given a sql query defined in the mappings. - * - * @param memento The representation of the defined . - * @param session The session to which this NativeQuery belongs. - * @param parameterMetadata Metadata about parameters found in the query. */ public NativeQueryImpl( NamedNativeQueryMemento memento, - SharedSessionContractImplementor session, - ParameterMetadata parameterMetadata) { - super( session, parameterMetadata ); + Class resultJavaType, + SharedSessionContractImplementor session) { + super( session ); + this.sqlString = memento.getSqlString(); - this.sqlString = memento.getQueryString(); - this.querySpaces = memento.getQuerySpaces() == null ? null : new ArrayList<>( memento.getQuerySpaces() ); + final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session ); - if ( memento.getResultSetRef() != null ) { - ResultSetMappingDescriptor definition = session.getFactory() - .getNamedQueryRepository() - .getResultSetMappingDefinition( memento.getResultSetRef() ); - if ( definition == null ) { - throw new MappingException( - "Unable to find resultset-ref definition: " + - memento.getResultSetRef() - ); - } - this.queryReturns = new ArrayList<>( Arrays.asList( definition.getQueryReturns() ) ); - } - else if ( memento.getQueryReturns() != null && memento.getQueryReturns().length > 0 ) { - this.queryReturns = new ArrayList<>( Arrays.asList( memento.getQueryReturns() ) ); - } - else { - this.queryReturns = new ArrayList<>(); - } - - - this.queryParameterBindings = QueryParameterBindingsImpl.from( - parameterMetadata, - session.getFactory(), - session.isQueryParametersValidationEnabled() - ); + this.parameterMetadata = parameterInterpretation.toParameterMetadata( session ); + this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters(); + this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() ); applyOptions( memento ); + + // todo (6.0) : validate `resultJavaType` against specified result-set mapping } - public NativeQueryImpl( - String sqlString, - boolean callable, - SharedSessionContractImplementor session, - ParameterMetadata sqlParameterMetadata) { - super( session, sqlParameterMetadata ); + private ParameterInterpretation resolveParameterInterpretation(SharedSessionContractImplementor session) { + final SessionFactoryImplementor sessionFactory = session.getFactory(); + final QueryEngine queryEngine = sessionFactory.getQueryEngine(); + final QueryInterpretationCache interpretationCache = queryEngine.getInterpretationCache(); + + return interpretationCache.resolveNativeQueryParameters( + sqlString, + s -> { + final ParameterRecognizerImpl parameterRecognizer = new ParameterRecognizerImpl( session.getFactory() ); + + session.getFactory().getServiceRegistry() + .getService( NativeQueryInterpreter.class ) + .recognizeParameters( sqlString, parameterRecognizer ); + + return new ParameterInterpretation() { + @Override + public List> getOccurrenceOrderedParameters() { + return parameterRecognizer.getParameterList(); + } + + @Override + public ParameterMetadataImplementor toParameterMetadata(SharedSessionContractImplementor session1) { + return new ParameterMetadataImpl( + parameterRecognizer.getPositionalQueryParameters(), + parameterRecognizer.getNamedQueryParameters() + ); + } + }; + } + ); + } + + protected void applyOptions(NamedNativeQueryMemento memento) { + super.applyOptions( memento ); + + this.querySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() ); + + // todo (6.0) : query returns + } + + public NativeQueryImpl(String sqlString, SharedSessionContractImplementor session) { + super( session ); + + this.sqlString = sqlString; this.queryReturns = new ArrayList<>(); - this.sqlString = sqlString; - this.querySpaces = new ArrayList<>(); + this.querySpaces = new HashSet<>(); - this.queryParameterBindings = QueryParameterBindingsImpl.from( - sqlParameterMetadata, - session.getFactory(), - session.isQueryParametersValidationEnabled() - ); - } - - @Override - protected QueryParameterBindings getQueryParameterBindings() { - return queryParameterBindings; - } - - @Override - public NativeQuery setResultSetMapping(String name) { - NamedResultSetMappingMemento mapping = getSession().getFactory().getQueryEngine().getNamedQueryRepository().getResultSetMappingMemento( name ); - if ( mapping == null ) { - throw new MappingException( "Unknown SqlResultSetMapping [" + name + "]" ); - } - NativeSQLQueryReturn[] returns = mapping.getQueryReturns(); - queryReturns.addAll( Arrays.asList( returns ) ); - return this; + final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session ); + this.parameterMetadata = parameterInterpretation.toParameterMetadata( session ); + this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters(); + this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() ); } @Override @@ -164,42 +196,236 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } @Override - public boolean isCallable() { - return callable; + public ParameterMetadataImplementor getParameterMetadata() { + return parameterMetadata; } @Override - public List getQueryReturns() { - prepareQueryReturnsIfNecessary(); - return queryReturns; + public MutableQueryOptions getQueryOptions() { + return queryOptions; } @Override - @SuppressWarnings("unchecked") - protected List doList() { - return getProducer().list( - generateQuerySpecification(), - getQueryParameters() - ); - } - - private NativeSQLQuerySpecification generateQuerySpecification() { - return new NativeSQLQuerySpecification( - getQueryParameterBindings().expandListValuedParameters( getQueryString(), getProducer() ), - queryReturns.toArray( new NativeSQLQueryReturn[queryReturns.size()] ), - querySpaces - ); + public DomainParameterBindingContext getDomainParameterBindingContext() { + return this; } @Override - public QueryParameters getQueryParameters() { - final QueryParameters queryParameters = super.getQueryParameters(); - queryParameters.setCallable( callable ); - queryParameters.setAutoDiscoverScalarTypes( autoDiscoverTypes ); - if ( collectionKey != null ) { - queryParameters.setCollectionKeys( new Serializable[] {collectionKey} ); + public Callback getCallback() { + throw new NotYetImplementedFor6Exception(); + } + + @Override + public SessionFactoryImplementor getSessionFactory() { + return getSession().getFactory(); + } + + @Override + public List getLoadIdentifiers() { + //noinspection unchecked + return (List) Collections.singletonList( collectionKey ); + } + + @Override + public QueryParameterBindings getQueryParameterBindings() { + return parameterBindings; + } + + @Override + public QueryParameterBindings getParameterBindings() { + return getQueryParameterBindings(); + } + + @Override + public NamedNativeQueryMemento toMemento(String name) { + throw new NotYetImplementedFor6Exception( ); + } + + @Override + protected boolean canApplyAliasSpecificLockModes() { + return false; + } + + @Override + protected void verifySettingLockMode() { + throw new IllegalStateException( "Illegal attempt to set lock mode on a native query" ); + } + + @Override + protected void verifySettingAliasSpecificLockModes() { + throw new IllegalStateException( "Illegal attempt to set lock mode on a native query" ); + } + + @Override + public Query applyGraph(RootGraph graph, GraphSemantic semantic) { + throw new HibernateException( "A native SQL query cannot use EntityGraphs" ); + } + + @Override + public NativeQueryImplementor setTupleTransformer(TupleTransformer transformer) { + //noinspection unchecked + return (NativeQueryImplementor) super.setTupleTransformer( transformer ); + } + + @Override + public NativeQueryImplementor setResultListTransformer(ResultListTransformer transformer) { + //noinspection unchecked + return (NativeQueryImplementor) super.setResultListTransformer( transformer ); + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Execution + + @Override + protected void prepareForExecution() { + if ( getSynchronizedQuerySpaces() != null && !getSynchronizedQuerySpaces().isEmpty() ) { + // The application defined query spaces on the Hibernate NativeQuery + // which means the query will already perform a partial flush + // according to the defined query spaces, no need to do a full flush. + return; } - return queryParameters; + + // otherwise we need to flush. the query itself is not required to execute + // in a transaction; if there is no transaction, the flush would throw a + // TransactionRequiredException which would potentially break existing + // apps, so we only do the flush if a transaction is in progress. + // + // NOTE : this was added for JPA initially. Perhaps we want to only do + // this from JPA usage? + if ( shouldFlush() ) { + getSession().flush(); + } + } + + private boolean shouldFlush() { + if ( getSession().isTransactionInProgress() ) { + FlushMode effectiveFlushMode = getHibernateFlushMode(); + if ( effectiveFlushMode == null ) { + effectiveFlushMode = getSession().getHibernateFlushMode(); + } + + if ( effectiveFlushMode == FlushMode.ALWAYS ) { + return true; + } + + if ( effectiveFlushMode == FlushMode.AUTO ) { + if ( getSession().getFactory().getSessionFactoryOptions().isJpaBootstrap() ) { + return true; + } + } + } + + return false; + } + + @Override + protected List doList() { + //noinspection unchecked + return resolveSelectQueryPlan().performList( this ); + } + + @SuppressWarnings("unchecked") + private SelectQueryPlan resolveSelectQueryPlan() { + final NativeQueryInterpreter interpreter = getSessionFactory().getServiceRegistry().getService( NativeQueryInterpreter.class ); + + SelectQueryPlan queryPlan = null; + + + final JdbcValuesMappingDescriptor resultSetMapping = resolveResultMapping(); + final RowTransformer rowTransformer = resolveRowTransformer(); + + final QueryInterpretationCache.Key cacheKey = generateSelectInterpretationsKey( resultSetMapping ); + if ( cacheKey != null ) { + queryPlan = getSession().getFactory().getQueryEngine().getInterpretationCache().getSelectQueryPlan( cacheKey ); + } + + if ( queryPlan == null ) { + queryPlan = interpreter.createQueryPlan( + generateSelectQueryDefinition(), + getSessionFactory() + ); + if ( cacheKey != null ) { + getSession().getFactory() + .getQueryEngine() + .getInterpretationCache() + .cacheSelectQueryPlan( cacheKey, queryPlan ); + } + } + + return queryPlan; + } + + private JdbcValuesMappingDescriptor resolveResultMapping() { + // todo (6.0) - need to resolve SqlSelections as well as resolving ResultBuilders and FetchBuilders into QueryResult trees + // also need to account for the edge case where the user passed just the + // query string and no mappings (see ResultSetMappingUndefinedImpl) + throw new NotYetImplementedFor6Exception( ); + } + + private RowTransformer resolveRowTransformer() { + // todo (6.0) - need to resolve the RowTransformer to use, if one. + // todo (6.0) - what about ResultListTransformer? + throw new NotYetImplementedFor6Exception( ); + } + + private SelectInterpretationsKey generateSelectInterpretationsKey(JdbcValuesMappingDescriptor resultSetMapping) { + if ( !isCacheable( this ) ) { + return null; + } + + return new SelectInterpretationsKey( + getQueryString(), + resultSetMapping, + getQueryOptions().getTupleTransformer(), + getQueryOptions().getResultListTransformer() + ); + } + + @SuppressWarnings("RedundantIfStatement") + private static boolean isCacheable(NativeQueryImpl query) { + if ( hasLimit( query.getQueryOptions().getLimit() ) ) { + return false; + } + + return true; + } + + private static boolean hasLimit(Limit limit) { + return limit.getFirstRow() != null || limit.getMaxRows() != null; + } + + private NativeSelectQueryDefinition generateSelectQueryDefinition() { + return new NativeSelectQueryDefinition() { + @Override + public String getSqlString() { + return NativeQueryImpl.this.getQueryString(); + } + + @Override + public boolean isCallable() { + return false; + } + + @Override + public List> getQueryParameterList() { + return NativeQueryImpl.this.occurrenceOrderedParamList; + } + + @Override + public JdbcValuesMappingDescriptor getResultSetMapping() { + return NativeQueryImpl.this.resolveResultMapping(); + } + + @Override + public RowTransformer getRowTransformer() { + return NativeQueryImpl.this.resolveRowTransformer(); + } + + @Override + public Set getAffectedTableNames() { + return querySpaces; + } + }; } private void prepareQueryReturnsIfNecessary() { @@ -221,17 +447,11 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI @Override protected ScrollableResultsImplementor doScroll(ScrollMode scrollMode) { - final NativeSQLQuerySpecification nativeSQLQuerySpecification = generateQuerySpecification(); - final QueryParameters queryParameters = getQueryParameters(); - queryParameters.setScrollMode( scrollMode ); - return getProducer().scroll( - nativeSQLQuerySpecification, - queryParameters - ); + return resolveSelectQueryPlan().performScroll( scrollMode, this ); } @Override - protected void beforeQuery() { + protected void beforeQuery(boolean txnRequired) { prepareQueryReturnsIfNecessary(); boolean noReturns = queryReturns == null || queryReturns.isEmpty(); if ( noReturns ) { @@ -253,8 +473,7 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } } - super.beforeQuery(); - + super.beforeQuery( txnRequired ); if ( getSynchronizedQuerySpaces() != null && !getSynchronizedQuerySpaces().isEmpty() ) { // The application defined query spaces on the Hibernate native SQLQuery which means the query will already @@ -268,40 +487,38 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI // // NOTE : this was added for JPA initially. Perhaps we want to only do this from JPA usage? if ( shouldFlush() ) { - getProducer().flush(); + getSession().flush(); } } - @Override - public Iterator iterate() { - throw new UnsupportedOperationException( "SQL queries do not currently support iteration" ); - } - - private boolean shouldFlush() { - if ( getProducer().isTransactionInProgress() ) { - FlushMode effectiveFlushMode = getHibernateFlushMode(); - if ( effectiveFlushMode == null ) { - effectiveFlushMode = getProducer().getHibernateFlushMode(); - } - - if ( effectiveFlushMode == FlushMode.ALWAYS ) { - return true; - } - - if ( effectiveFlushMode == FlushMode.AUTO ) { - if ( getProducer().getFactory().getSessionFactoryOptions().isJpaBootstrap() ) { - return true; - } - } - } - - return false; - } - protected int doExecuteUpdate() { - return getProducer().executeNativeUpdate( - generateQuerySpecification(), - getQueryParameters() + return resolveNonSelectQueryPlan().executeUpdate( this ); + } + + private NonSelectQueryPlan resolveNonSelectQueryPlan() { + NonSelectQueryPlan queryPlan = null; + + final QueryInterpretationCache.Key cacheKey = generateNonSelectInterpretationsKey(); + if ( cacheKey != null ) { + queryPlan = getSession().getFactory().getQueryEngine().getInterpretationCache().getNonSelectQueryPlan( cacheKey ); + } + + if ( queryPlan == null ) { + queryPlan = new NativeNonSelectQueryPlanImpl( this ); + if ( cacheKey != null ) { + getSession().getFactory().getQueryEngine().getInterpretationCache().cacheNonSelectQueryPlan( cacheKey, queryPlan ); + } + } + + return queryPlan; + } + + + protected NonSelectInterpretationsKey generateNonSelectInterpretationsKey() { + // todo (6.0) - should this account for query-spaces in determining "cacheable"? + return new NonSelectInterpretationsKey( + getQueryString(), + getSynchronizedQuerySpaces() ); } @@ -312,12 +529,17 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } @Override - public NativeQueryImplementor addScalar(String columnAlias) { - return addScalar( columnAlias, null ); + public NativeQueryImplementor addScalar(String columnAlias) { + return addScalar( columnAlias, (BasicDomainType) null ); } @Override - public NativeQueryImplementor addScalar(String columnAlias, Type type) { + public NativeQueryImplementor addScalar(String columnAlias, BasicDomainType type) { + return null; + } + + @Override + public NativeQueryImplementor addScalar(String columnAlias, Type type) { addReturnBuilder( new NativeQueryReturnBuilder() { public NativeSQLQueryReturn buildReturn() { @@ -349,34 +571,34 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } @Override - public NativeQueryImplementor addEntity(String entityName) { + public NativeQueryImplementor addEntity(String entityName) { return addEntity( StringHelper.unqualify( entityName ), entityName ); } @Override - public NativeQueryImplementor addEntity(String tableAlias, String entityName) { + public NativeQueryImplementor addEntity(String tableAlias, String entityName) { addRoot( tableAlias, entityName ); return this; } @Override - public NativeQueryImplementor addEntity(String tableAlias, String entityName, LockMode lockMode) { + public NativeQueryImplementor addEntity(String tableAlias, String entityName, LockMode lockMode) { addRoot( tableAlias, entityName ).setLockMode( lockMode ); return this; } @Override - public NativeQueryImplementor addEntity(Class entityType) { + public NativeQueryImplementor addEntity(Class entityType) { return addEntity( entityType.getName() ); } @Override - public NativeQueryImplementor addEntity(String tableAlias, Class entityClass) { + public NativeQueryImplementor addEntity(String tableAlias, Class entityClass) { return addEntity( tableAlias, entityClass.getName() ); } @Override - public NativeQueryImplementor addEntity(String tableAlias, Class entityClass, LockMode lockMode) { + public NativeQueryImplementor addEntity(String tableAlias, Class entityClass, LockMode lockMode) { return addEntity( tableAlias, entityClass.getName(), lockMode ); } @@ -388,7 +610,7 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } @Override - public NativeQueryImplementor addJoin(String tableAlias, String path) { + public NativeQueryImplementor addJoin(String tableAlias, String path) { createFetchJoin( tableAlias, path ); return this; } @@ -404,46 +626,24 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI } @Override - public NativeQueryImplementor addJoin(String tableAlias, String ownerTableAlias, String joinPropertyName) { + public NativeQueryImplementor addJoin(String tableAlias, String ownerTableAlias, String joinPropertyName) { addFetch( tableAlias, ownerTableAlias, joinPropertyName ); return this; } @Override - public NativeQueryImplementor addJoin(String tableAlias, String path, LockMode lockMode) { + public NativeQueryImplementor addJoin(String tableAlias, String path, LockMode lockMode) { createFetchJoin( tableAlias, path ).setLockMode( lockMode ); return this; } - @Override - public String[] getReturnAliases() { - throw new UnsupportedOperationException( "Native (SQL) queries do not support returning aliases" ); - } - - @Override - public Type[] getReturnTypes() { - throw new UnsupportedOperationException( "Native (SQL) queries do not support returning 'return types'" ); - } - - @Override - public NativeQueryImplementor setEntity(int position, Object val) { - setParameter( position, val, getProducer().getFactory().getTypeHelper().entity( resolveEntityName( val ) ) ); - return this; - } - - @Override - public NativeQueryImplementor setEntity(String name, Object val) { - setParameter( name, val, getProducer().getFactory().getTypeHelper().entity( resolveEntityName( val ) ) ); - return this; - } - @Override public Collection getSynchronizedQuerySpaces() { return querySpaces; } @Override - public NativeQueryImplementor addSynchronizedQuerySpace(String querySpace) { + public NativeQueryImplementor addSynchronizedQuerySpace(String querySpace) { addQuerySpaces( querySpace ); return this; } @@ -451,7 +651,7 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI protected void addQuerySpaces(String... spaces) { if ( spaces != null ) { if ( querySpaces == null ) { - querySpaces = new ArrayList<>(); + querySpaces = new HashSet<>(); } querySpaces.addAll( Arrays.asList( (String[]) spaces ) ); } @@ -460,108 +660,123 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI protected void addQuerySpaces(Serializable... spaces) { if ( spaces != null ) { if ( querySpaces == null ) { - querySpaces = new ArrayList<>(); + querySpaces = new HashSet<>(); } querySpaces.addAll( Arrays.asList( (String[]) spaces ) ); } } @Override - public NativeQueryImplementor addSynchronizedEntityName(String entityName) throws MappingException { - addQuerySpaces( getProducer().getFactory().getMetamodel().entityPersister( entityName ).getQuerySpaces() ); + public NativeQueryImplementor addSynchronizedEntityName(String entityName) throws MappingException { + addQuerySpaces( getSession().getFactory().getMetamodel().entityPersister( entityName ).getQuerySpaces() ); return this; } @Override - public NativeQueryImplementor addSynchronizedEntityClass(Class entityClass) throws MappingException { - addQuerySpaces( getProducer().getFactory().getMetamodel().entityPersister( entityClass.getName() ).getQuerySpaces() ); + public NativeQueryImplementor addSynchronizedEntityClass(Class entityClass) throws MappingException { + addQuerySpaces( getSession().getFactory().getMetamodel().entityPersister( entityClass.getName() ).getQuerySpaces() ); return this; } @Override - protected boolean isNativeQuery() { - return true; - } - - @Override - public NativeQueryImplementor setHibernateFlushMode(FlushMode flushMode) { + public NativeQueryImplementor setHibernateFlushMode(FlushMode flushMode) { super.setHibernateFlushMode( flushMode ); return this; } @Override - public NativeQueryImplementor setFlushMode(FlushMode flushMode) { - super.setFlushMode( flushMode ); - return this; - } - - @Override - public NativeQueryImplementor setFlushMode(FlushModeType flushModeType) { + public NativeQueryImplementor setFlushMode(FlushModeType flushModeType) { super.setFlushMode( flushModeType ); return this; } @Override - public NativeQueryImplementor setCacheMode(CacheMode cacheMode) { + public NativeQueryImplementor setCacheMode(CacheMode cacheMode) { super.setCacheMode( cacheMode ); return this; } @Override - public NativeQueryImplementor setCacheable(boolean cacheable) { + public NativeQueryImplementor setCacheable(boolean cacheable) { super.setCacheable( cacheable ); return this; } @Override - public NativeQueryImplementor setCacheRegion(String cacheRegion) { + public NativeQueryImplementor setCacheRegion(String cacheRegion) { super.setCacheRegion( cacheRegion ); return this; } @Override - public NativeQueryImplementor setTimeout(int timeout) { + public NativeQueryImplementor setTimeout(int timeout) { super.setTimeout( timeout ); return this; } @Override - public NativeQueryImplementor setFetchSize(int fetchSize) { + public NativeQueryImplementor setFetchSize(int fetchSize) { super.setFetchSize( fetchSize ); return this; } @Override - public NativeQueryImplementor setReadOnly(boolean readOnly) { + public NativeQueryImplementor setReadOnly(boolean readOnly) { super.setReadOnly( readOnly ); return this; } @Override - public NativeQueryImplementor setLockOptions(LockOptions lockOptions) { + public NativeQueryImplementor setLockOptions(LockOptions lockOptions) { super.setLockOptions( lockOptions ); return this; } @Override - public NativeQueryImplementor setLockMode(String alias, LockMode lockMode) { + public NativeQueryImplementor setLockMode(String alias, LockMode lockMode) { super.setLockMode( alias, lockMode ); return this; } @Override - public NativeQueryImplementor setLockMode(LockModeType lockModeType) { + public NativeQueryImplementor setLockMode(LockModeType lockModeType) { throw new IllegalStateException( "Illegal attempt to set lock mode on a native SQL query" ); } @Override - public NativeQueryImplementor setComment(String comment) { + @SuppressWarnings("unchecked") + public T unwrap(Class javaType) { + if ( javaType.isAssignableFrom( getClass() ) ) { + return (T) this; + } + + if ( javaType.isAssignableFrom( ParameterMetadata.class ) ) { + return (T) parameterMetadata; + } + + if ( javaType.isAssignableFrom( QueryParameterBindings.class ) ) { + return (T) parameterBindings; + } + + if ( javaType.isAssignableFrom( EntityManager.class ) ) { + return (T) getSession(); + } + + if ( javaType.isAssignableFrom( EntityManagerFactory.class ) ) { + return (T) getSession().getFactory(); + } + + throw new PersistenceException( "Unrecognized unwrap type [" + javaType.getName() + "]" ); + } + + @Override + public NativeQueryImplementor setComment(String comment) { super.setComment( comment ); return this; } @Override - public NativeQueryImplementor addQueryHint(String hint) { + public NativeQueryImplementor addQueryHint(String hint) { super.addQueryHint( hint ); return this; } @@ -575,10 +790,10 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI @Override protected boolean applyNativeQueryLockMode(Object value) { - if ( LockMode.class.isInstance( value ) ) { + if ( value instanceof LockMode ) { applyHibernateLockModeHint( (LockMode) value ); } - else if ( LockModeType.class.isInstance( value ) ) { + else if ( value instanceof LockModeType ) { applyLockModeTypeHint( (LockModeType) value ); } else { @@ -598,249 +813,324 @@ public class NativeQueryImpl extends AbstractQuery implements NativeQueryI @Override @SuppressWarnings("unchecked") - public NativeQueryImplementor setParameter(QueryParameter parameter, Object value) { + public NativeQueryImplementor setParameter(QueryParameter parameter, Object value) { super.setParameter( (Parameter) parameter, value ); return this; } @Override - public

NativeQueryImplementor setParameter(Parameter

parameter, P value) { + public

NativeQueryImplementor setParameter(Parameter

parameter, P value) { super.setParameter( parameter, value ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Object value) { + public NativeQueryImplementor setParameter(String name, Object value) { super.setParameter( name, value ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Object value) { + public NativeQueryImplementor setParameter(int position, Object value) { super.setParameter( position, value ); return this; } @Override @SuppressWarnings("unchecked") - public NativeQueryImplementor setParameter(QueryParameter parameter, Object value, Type type) { + public NativeQueryImplementor setParameter(QueryParameter parameter, Object value, Type type) { super.setParameter( parameter, value, type ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Object value, Type type) { + public NativeQueryImplementor setParameter(String name, Object value, Type type) { super.setParameter( name, value, type ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Object value, Type type) { + public NativeQueryImplementor setParameter(int position, Object value, Type type) { super.setParameter( position, value, type ); return this; } @Override - public

NativeQueryImplementor setParameter(QueryParameter

parameter, P value, TemporalType temporalType) { + public

NativeQueryImplementor setParameter(QueryParameter

parameter, P value, TemporalType temporalType) { super.setParameter( parameter, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Object value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, Object value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Object value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, Object value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(Parameter param, Instant value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, Instant value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(Parameter param, LocalDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, LocalDateTime value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(Parameter param, ZonedDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, ZonedDateTime value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(Parameter param, OffsetDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, OffsetDateTime value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Instant value, TemporalType temporalType) { + public NativeQueryImplementor setParameterList(int position, Collection values, Type type) { + return setParameterList( position, values, ( AllowableParameterType) type ); + } + + @Override + public NativeQueryImplementor setParameterList(String name, Collection values, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( name, values, type ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Collection values, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( position, values, type ); + } + + @Override + public NativeQueryImplementor setParameterList(String name, Object[] values, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( name, values, type ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Object[] values, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( position, values, type ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Object[] values, Type type) { + return null; + } + + @Override + public NativeQueryImplementor setParameter(String name, Instant value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, LocalDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, LocalDateTime value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, ZonedDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, ZonedDateTime value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, OffsetDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, OffsetDateTime value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Instant value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, Instant value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, LocalDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, LocalDateTime value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, ZonedDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, ZonedDateTime value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, OffsetDateTime value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, OffsetDateTime value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameterList(QueryParameter parameter, Collection values) { + public NativeQueryImplementor setParameterList(QueryParameter parameter, Collection values) { super.setParameterList( parameter, values ); return this; } @Override - public NativeQueryImplementor setParameterList(String name, Collection values) { + public NativeQueryImplementor setParameterList(String name, Collection values) { super.setParameterList( name, values ); return this; } @Override - public NativeQueryImplementor setParameterList(String name, Collection values, Type type) { + public NativeQueryImplementor setParameterList(String name, Collection values, Type type) { super.setParameterList( name, values, type ); return this; } @Override - public NativeQueryImplementor setParameterList(String name, Object[] values, Type type) { + public NativeQueryImplementor setParameterList(String name, Object[] values, Type type) { super.setParameterList( name, values, type ); return this; } @Override - public NativeQueryImplementor setParameterList(String name, Object[] values) { + public NativeQueryImplementor setParameterList(String name, Object[] values) { super.setParameterList( name, values ); return this; } @Override @SuppressWarnings("unchecked") - public NativeQueryImplementor setParameter(Parameter param, Calendar value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, Calendar value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override @SuppressWarnings("unchecked") - public NativeQueryImplementor setParameter(Parameter param, Date value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(Parameter param, Date value, TemporalType temporalType) { super.setParameter( param, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Calendar value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, Calendar value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(String name, Date value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(String name, Date value, TemporalType temporalType) { super.setParameter( name, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Calendar value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, Calendar value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setParameter(int position, Date value, TemporalType temporalType) { + public NativeQueryImplementor setParameter(int position, Date value, TemporalType temporalType) { super.setParameter( position, value, temporalType ); return this; } @Override - public NativeQueryImplementor setResultTransformer(ResultTransformer transformer) { + public NativeQueryImplementor setResultTransformer(ResultTransformer transformer) { super.setResultTransformer( transformer ); return this; } @Override - public NativeQueryImplementor setProperties(Map map) { + public NativeQueryImplementor setProperties(Map map) { super.setProperties( map ); return this; } @Override - public NativeQueryImplementor setProperties(Object bean) { + public NativeQueryImplementor setProperties(Object bean) { super.setProperties( bean ); return this; } @Override - public NativeQueryImplementor setMaxResults(int maxResult) { + public NativeQueryImplementor setMaxResults(int maxResult) { super.setMaxResults( maxResult ); return this; } @Override - public NativeQueryImplementor setFirstResult(int startPosition) { + public NativeQueryImplementor setFirstResult(int startPosition) { super.setFirstResult( startPosition ); return this; } @Override - public NativeQueryImplementor setHint(String hintName, Object value) { + public

NativeQueryImplementor setParameter(QueryParameter

parameter, P value, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameter( parameter, value, type ); + } + + @Override + public NativeQueryImplementor setParameter(String name, Object value, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameter( name, value, type ); + } + + @Override + public NativeQueryImplementor setParameter(int position, Object value, AllowableParameterType type) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameter( position, value, type ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Collection values) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( position, values ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Object[] values) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( position, values ); + } + + @Override + public NativeQueryImplementor setParameterList(String name, Collection values, Class javaType) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( name, values, javaType ); + } + + @Override + public NativeQueryImplementor setParameterList(int position, Collection values, Class javaType) { + //noinspection unchecked + return (NativeQueryImplementor) super.setParameterList( position, values, javaType ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Hints + + @Override + public NativeQueryImplementor setHint(String hintName, Object value) { super.setHint( hintName, value ); return this; } @Override - public Query applyGraph(RootGraph graph, GraphSemantic semantic) { - throw new HibernateException( "A native SQL query cannot use EntityGraphs" ); - } - - @Override - protected void applyEntityGraphQueryHint(EntityGraphQueryHint hint) { + protected void applyEntityGraphQueryHint(String hintName, RootGraphImplementor entityGraph) { throw new HibernateException( "A native SQL query cannot use EntityGraphs" ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java new file mode 100644 index 0000000000..104651acef --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java @@ -0,0 +1,127 @@ +/* + * 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.internal; + +import java.util.List; +import java.util.Set; + +import org.hibernate.ScrollMode; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.query.spi.QueryParameterBinding; +import org.hibernate.query.spi.QueryParameterImplementor; +import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.query.sql.spi.NativeSelectQueryPlan; +import org.hibernate.sql.ast.Clause; +import org.hibernate.sql.exec.spi.ExecutionContext; +import org.hibernate.sql.exec.spi.JdbcParameterBinder; +import org.hibernate.sql.exec.spi.JdbcParameterBindings; +import org.hibernate.sql.exec.spi.JdbcSelect; +import org.hibernate.sql.exec.spi.JdbcSelectExecutor; +import org.hibernate.sql.results.spi.JdbcValuesMappingDescriptor; +import org.hibernate.sql.results.spi.RowTransformer; + +/** + * @author Steve Ebersole + */ +public class NativeSelectQueryPlanImpl implements NativeSelectQueryPlan { + private final String sql; + private final Set affectedTableNames; + + private final List> parameterList; + + private final JdbcValuesMappingDescriptor resultSetMapping; + private final RowTransformer rowTransformer; + + public NativeSelectQueryPlanImpl( + String sql, + Set affectedTableNames, + List> parameterList, + JdbcValuesMappingDescriptor resultSetMapping, + RowTransformer rowTransformer) { + this.sql = sql; + this.affectedTableNames = affectedTableNames; + this.parameterList = parameterList; + this.resultSetMapping = resultSetMapping; + this.rowTransformer = rowTransformer; + } + + @Override + public List performList(ExecutionContext executionContext) { + final List jdbcParameterBinders = resolveJdbcParameterBinders( executionContext ); + + final JdbcSelect jdbcSelect = new JdbcSelectImpl( + sql, + jdbcParameterBinders, + resultSetMapping, + affectedTableNames + ); + + // todo (6.0) : need to make this swappable (see note in executor class) + final JdbcSelectExecutor executor = JdbcSelectExecutorStandardImpl.INSTANCE; + + return executor.list( jdbcSelect, JdbcParameterBindings.NO_BINDINGS, executionContext, rowTransformer ); + } + + private List resolveJdbcParameterBinders(ExecutionContext executionContext) { + final List jdbcParameterBinders = CollectionHelper.arrayList( parameterList.size() ); + + for ( QueryParameterImplementor parameter : parameterList ) { + final QueryParameterBinding parameterBinding = executionContext.getDomainParameterBindingContext() + .getQueryParameterBindings() + .getBinding( parameter ); + AllowableParameterType type = parameterBinding.getBindType(); + if ( type == null ) { + type = parameter.getHibernateType(); + } + + type.dehydrate( + type.unresolve( parameterBinding.getBindValue(), executionContext.getSession() ), + (jdbcValue, sqlExpressableType, boundColumn) -> jdbcParameterBinders.add( + (statement, startPosition, jdbcParameterBindings, executionContext1) -> { + //noinspection unchecked + sqlExpressableType.getJdbcValueBinder().bind( + statement, + startPosition, + jdbcValue, + executionContext1 + ); + return 1; + } + ), + Clause.IRRELEVANT, + executionContext.getSession() + ); + } + + return jdbcParameterBinders; + } + + @Override + public ScrollableResultsImplementor performScroll(ScrollMode scrollMode, ExecutionContext executionContext) { + // todo (6.0) : see notes above in `#performList` + + final List jdbcParameterBinders = resolveJdbcParameterBinders( executionContext ); + + final JdbcSelect jdbcSelect = new JdbcSelectImpl( + sql, + jdbcParameterBinders, + resultSetMapping, + affectedTableNames + ); + final JdbcSelectExecutor executor = JdbcSelectExecutorStandardImpl.INSTANCE; + + return executor.scroll( + jdbcSelect, + scrollMode, + // the binders created here encapsulate their bind value + JdbcParameterBindings.NO_BINDINGS, + executionContext, + rowTransformer + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java similarity index 61% rename from hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java rename to hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java index 45f628c495..a6765af751 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/ParameterParser.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java @@ -1,66 +1,32 @@ /* * 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 . + * 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.engine.query.spi; +package org.hibernate.query.sql.internal; + +import java.util.BitSet; import org.hibernate.QueryException; -import org.hibernate.hql.internal.classic.ParserHelper; import org.hibernate.internal.util.StringHelper; +import org.hibernate.query.sql.spi.ParameterRecognizer; /** * The single available method {@link #parse} is responsible for parsing a - * query string and recognizing tokens in relation to parameters (either - * named, JPA-style, or ordinal) and providing callbacks about such - * recognitions. + * native query string and recognizing tokens defining named of ordinal + * parameters and providing callbacks about each recognition. * * @author Steve Ebersole */ public class ParameterParser { - /** - * Maybe better named a Journaler. Essentially provides a callback contract for things that recognize parameters - */ - public interface Recognizer { - /** - * Called when an output parameter is recognized - * - * @param position The position within the query - */ - void outParameter(int position); + private static final String HQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\"; + private static final BitSet HQL_SEPARATORS_BITSET = new BitSet(); - /** - * Called when an ordinal parameter is recognized - * - * @param position The position within the query - */ - void ordinalParameter(int position); - - /** - * Called when a named parameter is recognized - * - * @param name The recognized parameter name - * @param position The position within the query - */ - void namedParameter(String name, int position); - - /** - * Called when a JPA-style named parameter is recognized - * - * @param identifier The identifier (name) of the JPA-style parameter - * @param position The position within the query - */ - void jpaPositionalParameter(int identifier, int position); - - /** - * Called when a character that is not a parameter (or part of a parameter dfinition) is recognized. - * - * @param character The recognized character - */ - void other(char character); - - void complete(); + static { + for ( int i = 0; i < HQL_SEPARATORS.length(); i++ ) { + HQL_SEPARATORS_BITSET.set( HQL_SEPARATORS.charAt( i ) ); + } } /** @@ -81,10 +47,7 @@ public class ParameterParser { * @param recognizer The thing which handles recognition events. * @throws QueryException Indicates unexpected parameter conditions. */ - public static void parse(String sqlString, Recognizer recognizer) throws QueryException { - final boolean hasMainOutputParameter = startsWithEscapeCallTemplate( sqlString ); - boolean foundMainOutputParam = false; - + public static void parse(String sqlString, ParameterRecognizer recognizer) throws QueryException { final int stringLength = sqlString.length(); boolean inSingleQuotes = false; @@ -168,7 +131,7 @@ public class ParameterParser { } else if ( c == ':' ) { // named parameter - final int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS_BITSET, indx + 1 ); + final int right = StringHelper.firstIndexOfChar( sqlString, HQL_SEPARATORS_BITSET, indx + 1 ); final int chopLocation = right < 0 ? sqlString.length() : right; final String param = sqlString.substring( indx + 1, chopLocation ); if ( param.isEmpty() ) { @@ -183,7 +146,7 @@ public class ParameterParser { // could be either an ordinal or JPA-positional parameter if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) { // a peek ahead showed this as a JPA-positional parameter - final int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 ); + final int right = StringHelper.firstIndexOfChar( sqlString, HQL_SEPARATORS, indx + 1 ); final int chopLocation = right < 0 ? sqlString.length() : right; final String param = sqlString.substring( indx + 1, chopLocation ); // make sure this "name" is an integral @@ -196,13 +159,7 @@ public class ParameterParser { } } else { - if ( hasMainOutputParameter && !foundMainOutputParam ) { - foundMainOutputParam = true; - recognizer.outParameter( indx ); - } - else { - recognizer.ordinalParameter( indx ); - } + recognizer.ordinalParameter( indx ); } } else { @@ -214,42 +171,4 @@ public class ParameterParser { recognizer.complete(); } - /** - * Exposed as public solely for use from tests - * - * @param sqlString The SQL string to check - * - * @return true/false - */ - public static boolean startsWithEscapeCallTemplate(String sqlString) { - if ( ! ( sqlString.startsWith( "{" ) && sqlString.endsWith( "}" ) ) ) { - return false; - } - - final int chopLocation = sqlString.indexOf( "call" ); - if ( chopLocation <= 0 ) { - return false; - } - - final String checkString = sqlString.substring( 1, chopLocation + 4 ); - final String fixture = "?=call"; - int fixturePosition = 0; - boolean matches = true; - final int max = checkString.length(); - for ( int i = 0; i < max; i++ ) { - final char c = Character.toLowerCase( checkString.charAt( i ) ); - if ( Character.isWhitespace( c ) ) { - continue; - } - if ( c == fixture.charAt( fixturePosition ) ) { - fixturePosition++; - continue; - } - matches = false; - break; - } - - return matches; - } - } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterRecognizerImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterRecognizerImpl.java new file mode 100644 index 0000000000..74c2fbe880 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterRecognizerImpl.java @@ -0,0 +1,199 @@ +/* + * 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.internal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.QueryException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.internal.QueryParameterNamedImpl; +import org.hibernate.query.internal.QueryParameterPositionalImpl; +import org.hibernate.query.spi.QueryParameterImplementor; +import org.hibernate.query.sql.spi.ParameterRecognizer; + +/** + * @author Steve Ebersole + */ +public class ParameterRecognizerImpl implements ParameterRecognizer { + private enum ParameterStyle { + JDBC, + ORDINAL, + NAMED + } + + private final int ordinalParameterBase; + + private ParameterStyle parameterStyle; + + private Map> namedQueryParameters; + private Map> positionalQueryParameters; + + private int ordinalParameterImplicitPosition; + + private List> parameterList; + + @SuppressWarnings("WeakerAccess") + public ParameterRecognizerImpl(SessionFactoryImplementor factory) { + if ( factory.getSessionFactoryOptions().isJpaBootstrap() ) { + ordinalParameterBase = 1; + } + else { + final Integer configuredBase = factory.getSessionFactoryOptions().getNonJpaNativeQueryOrdinalParameterBase(); + ordinalParameterBase = configuredBase == null + ? 1 + : configuredBase; + } + assert ordinalParameterBase == 0 || ordinalParameterBase == 1; + + ordinalParameterImplicitPosition = ordinalParameterBase; + } + + @Override + public void complete() { + // validate the positions. JPA says that these should start with 1 and + // increment contiguously (no gaps) + if ( positionalQueryParameters != null ) { + final int[] positionsArray = positionalQueryParameters.keySet().stream().mapToInt( Integer::intValue ).toArray(); + Arrays.sort( positionsArray ); + int previous = 0; + boolean first = true; + for ( Integer position : positionsArray ) { + if ( position != previous + 1 ) { + if ( first ) { + throw new QueryException( "Positional parameters did not start with base [" + ordinalParameterBase + "] : " + position ); + } + else { + throw new QueryException( "Gap in positional parameter positions; skipped " + (previous+1) ); + } + } + first = false; + previous = position; + } + } + } + + public Map> getNamedQueryParameters() { + return namedQueryParameters; + } + + public Map> getPositionalQueryParameters() { + return positionalQueryParameters; + } + + public List> getParameterList() { + return parameterList; + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Recognition code + + @Override + public void ordinalParameter(int sourcePosition) { + if ( parameterStyle == null ) { + parameterStyle = ParameterStyle.JDBC; + } + else if ( parameterStyle != ParameterStyle.JDBC ) { + throw new IllegalStateException( "Cannot mix parameter styles between JDBC-style, ordinal and named in the same query" ); + } + + int implicitPosition = ordinalParameterImplicitPosition++; + + QueryParameterImplementor parameter = null; + + if ( positionalQueryParameters == null ) { + positionalQueryParameters = new HashMap<>(); + } + else { + parameter = positionalQueryParameters.get( implicitPosition ); + } + + if ( parameter == null ) { + parameter = QueryParameterPositionalImpl.fromNativeQuery( implicitPosition ); + positionalQueryParameters.put( implicitPosition, parameter ); + } + + if ( parameterList == null ) { + parameterList = new ArrayList<>(); + } + + parameterList.add( parameter ); + } + + @Override + public void namedParameter(String name, int sourcePosition) { + if ( parameterStyle == null ) { + parameterStyle = ParameterStyle.NAMED; + } + else if ( parameterStyle != ParameterStyle.NAMED ) { + throw new IllegalStateException( "Cannot mix parameter styles between JDBC-style, ordinal and named in the same query" ); + } + + QueryParameterImplementor parameter = null; + + if ( namedQueryParameters == null ) { + namedQueryParameters = new HashMap<>(); + } + else { + parameter = namedQueryParameters.get( name ); + } + + if ( parameter == null ) { + parameter = QueryParameterNamedImpl.fromNativeQuery( name ); + namedQueryParameters.put( name, parameter ); + } + + if ( parameterList == null ) { + parameterList = new ArrayList<>(); + } + + parameterList.add( parameter ); + } + + @Override + public void jpaPositionalParameter(int position, int sourcePosition) { + if ( parameterStyle == null ) { + parameterStyle = ParameterStyle.NAMED; + } + else if ( parameterStyle != ParameterStyle.NAMED ) { + throw new IllegalStateException( "Cannot mix parameter styles between JDBC-style, ordinal and named in the same query" ); + } + + if ( position < 1 ) { + throw new QueryException( "Incoming parameter position [" + position + "] is less than base [1]" ); + } + + QueryParameterImplementor parameter = null; + + if ( positionalQueryParameters == null ) { + positionalQueryParameters = new HashMap<>(); + } + else { + parameter = positionalQueryParameters.get( position ); + } + + if ( parameter == null ) { + parameter = QueryParameterPositionalImpl.fromNativeQuery( position ); + positionalQueryParameters.put( position, parameter ); + } + + if ( parameterList == null ) { + parameterList = new ArrayList<>(); + } + + parameterList.add( parameter ); + } + + @Override + public void other(char character) { + // don't care... + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java index 7c41079a60..58aba1932a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java @@ -8,7 +8,9 @@ package org.hibernate.query.sql.spi; import java.util.Set; +import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.spi.AbstractNamedQueryMemento; import org.hibernate.query.spi.NamedQueryMemento; @@ -25,6 +27,11 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento { */ String getSqlString(); + /** + * The affected query spaces. + */ + Set getQuerySpaces(); + /** * Convert the memento into a typed executable query */ @@ -96,12 +103,14 @@ public interface NamedNativeQueryMemento extends NamedQueryMemento { this.resultSetMappingClassName = resultSetMappingClassName; } - public NamedNativeQueryMemento build() { + public NamedNativeQueryMemento build(SessionFactoryImplementor sessionFactory) { return new NamedNativeQueryMementoImpl( name, queryString, resultSetMappingName, - resultSetMappingClassName, + sessionFactory.getServiceRegistry() + .getService( ClassLoaderService.class ) + .classForName( resultSetMappingClassName ), querySpaces, cacheable, cacheRegion, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryDefinition.java new file mode 100644 index 0000000000..0bad0e2179 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryDefinition.java @@ -0,0 +1,26 @@ +/* + * 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.spi; + +import java.util.List; + +import org.hibernate.sql.exec.spi.JdbcParameterBinder; + +/** + * Access the values defining a native non-select query + * + * @author Steve Ebersole + */ +public interface NativeNonSelectQueryDefinition { + String getSqlString(); + List getParameterBinders(); + + // todo (6.0) : affected table - either table names or Table references + + // todo (6.0) : drop support for executing callables via NativeQuery + boolean isCallable(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryPlan.java new file mode 100644 index 0000000000..1b132142a8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeNonSelectQueryPlan.java @@ -0,0 +1,18 @@ +/* + * 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.spi; + +import org.hibernate.query.spi.NonSelectQueryPlan; + +/** + * Union of {@link NonSelectQueryPlan} and {@link NativeQueryPlan} as the + * {@link NonSelectQueryPlan} for native-queries. + * + * @author Steve Ebersole + */ +public interface NativeNonSelectQueryPlan extends NativeQueryPlan, NonSelectQueryPlan { +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/NotYetImplementedException.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeQueryPlan.java similarity index 51% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/NotYetImplementedException.java rename to hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeQueryPlan.java index 0086633018..5f7a6d8b1e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/NotYetImplementedException.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeQueryPlan.java @@ -4,17 +4,15 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html */ -package org.hibernate.query.sqm; +package org.hibernate.query.sql.spi; + +import org.hibernate.query.spi.QueryPlan; /** + * Specialization of {@link QueryPlan} for {@link org.hibernate.query.NativeQuery} + * plans + * * @author Steve Ebersole */ -public class NotYetImplementedException extends RuntimeException { - public NotYetImplementedException(String message) { - super( message ); - } - - public NotYetImplementedException() { - super( "Not yet implemented" ); - } +public interface NativeQueryPlan extends QueryPlan { } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryDefinition.java new file mode 100644 index 0000000000..a8101b24aa --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryDefinition.java @@ -0,0 +1,40 @@ +/* + * 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.spi; + +import java.util.List; +import java.util.Set; + +import org.hibernate.query.spi.QueryParameterImplementor; +import org.hibernate.sql.results.spi.JdbcValuesMappingDescriptor; +import org.hibernate.sql.results.spi.RowTransformer; + +/** + * Access the values defining a native select query + * + * @author Steve Ebersole + */ +public interface NativeSelectQueryDefinition { + String getSqlString(); + + /** + * @apiNote This returns query parameters in the order they were + * encountered - potentially including "duplicate references" to a single parameter + */ + List> getQueryParameterList(); + + JdbcValuesMappingDescriptor getResultSetMapping(); + + Set getAffectedTableNames(); + + RowTransformer getRowTransformer(); + + + // todo (6.0) : drop support for executing callables via NativeQuery + boolean isCallable(); + +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryPlan.java new file mode 100644 index 0000000000..bab3680800 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeSelectQueryPlan.java @@ -0,0 +1,18 @@ +/* + * 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.spi; + +import org.hibernate.query.spi.SelectQueryPlan; + +/** + * Union of {@link SelectQueryPlan} and {@link NativeQueryPlan} as the + * {@link SelectQueryPlan} for native-queries. + * + * @author Steve Ebersole + */ +public interface NativeSelectQueryPlan extends SelectQueryPlan, NativeQueryPlan { +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NonSelectInterpretationsKey.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NonSelectInterpretationsKey.java new file mode 100644 index 0000000000..e12bf0e71c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NonSelectInterpretationsKey.java @@ -0,0 +1,26 @@ +/* + * 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.spi; + +import java.util.Collection; + +import org.hibernate.query.spi.QueryInterpretationCache; + +/** + * QueryInterpretations key for non-select NativeQuery instances + * + * @author Steve Ebersole + */ +public class NonSelectInterpretationsKey implements QueryInterpretationCache.Key { + private final String sql; + private final Collection querySpaces; + + public NonSelectInterpretationsKey(String sql, Collection querySpaces) { + this.sql = sql; + this.querySpaces = querySpaces; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterInterpretation.java new file mode 100644 index 0000000000..0298434e99 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterInterpretation.java @@ -0,0 +1,29 @@ +/* + * 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.spi; + +import java.util.List; + +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.query.spi.ParameterMetadataImplementor; +import org.hibernate.query.spi.QueryParameterImplementor; + +/** + * @author Steve Ebersole + */ +public interface ParameterInterpretation { + /** + * Access to the defined parameters in the order they were encountered, + * potentially including "duplicate references" to a single parameter + */ + List> getOccurrenceOrderedParameters(); + + /** + * Create the ParameterMetadata representation of this interpretation + */ + ParameterMetadataImplementor toParameterMetadata(SharedSessionContractImplementor session); +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterRecognizer.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterRecognizer.java new file mode 100644 index 0000000000..8a4affbd92 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/ParameterRecognizer.java @@ -0,0 +1,65 @@ +/* + * 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.spi; + +/** + * Defines the "callback" the process of recognizing native query parameters. + * + * @see org.hibernate.engine.query.spi.NativeQueryInterpreter#recognizeParameters + */ +public interface ParameterRecognizer { + /** + * Called when an output parameter is recognized. This should only ever be + * called once for a query in cases where the JDBC "function call" escape syntax is + * recognized, i.e. {@code "{?=call...}"} + * + * @param sourcePosition The position within the query + * + * @deprecated (since 5.2) Application should use {@link org.hibernate.procedure.ProcedureCall} instead + */ + @Deprecated + default void outParameter(int sourcePosition) { + throw new UnsupportedOperationException( "Recognizing native query as a function call is no longer supported" ); + } + + /** + * Called when an ordinal parameter is recognized + * + * @param sourcePosition The position within the query + */ + void ordinalParameter(int sourcePosition); + + /** + * Called when a named parameter is recognized + * + * @param name The recognized parameter name + * @param sourcePosition The position within the query + */ + void namedParameter(String name, int sourcePosition); + + /** + * Called when a JPA-style named parameter is recognized + * + * @param label The label (identifier) of the JPA-style parameter. e.g. for a parameter `?2`, the label is `2` + * @param sourcePosition The position within the query + */ + void jpaPositionalParameter(int label, int sourcePosition); + + /** + * Called when a character that is not part of a parameter is recognized. + * + * @param character The recognized character + */ + void other(char character); + + /** + * Callback after all parsing is complete + */ + default void complete() { + // by default, nothing to do + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java new file mode 100644 index 0000000000..e7a8e2dc54 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java @@ -0,0 +1,63 @@ +/* + * 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.spi; + +import java.util.Objects; + +import org.hibernate.query.ResultListTransformer; +import org.hibernate.query.TupleTransformer; +import org.hibernate.query.spi.QueryInterpretationCache; +import org.hibernate.sql.results.spi.JdbcValuesMappingDescriptor; + +/** + * @author Steve Ebersole + */ +public class SelectInterpretationsKey implements QueryInterpretationCache.Key { + private final String sql; + private final JdbcValuesMappingDescriptor resultSetMapping; + + private final TupleTransformer tupleTransformer; + private final ResultListTransformer resultListTransformer; + + public SelectInterpretationsKey( + String sql, + JdbcValuesMappingDescriptor resultSetMapping, + TupleTransformer tupleTransformer, + ResultListTransformer resultListTransformer) { + this.sql = sql; + this.resultSetMapping = resultSetMapping; + this.tupleTransformer = tupleTransformer; + this.resultListTransformer = resultListTransformer; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + SelectInterpretationsKey that = (SelectInterpretationsKey) o; + + return sql.equals( that.sql ) + && Objects.equals( resultSetMapping, that.resultSetMapping ) + && Objects.equals( tupleTransformer, that.tupleTransformer ) + && Objects.equals( resultListTransformer, that.resultListTransformer ); + + } + + @Override + public int hashCode() { + int result = sql.hashCode(); + result = 31 * result + resultSetMapping.hashCode(); + result = 31 * result + ( tupleTransformer != null ? tupleTransformer.hashCode() : 0 ); + result = 31 * result + ( resultListTransformer != null ? resultListTransformer.hashCode() : 0 ); + return result; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/IllegalPathUsageException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/IllegalPathUsageException.java new file mode 100644 index 0000000000..10f23a380d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/IllegalPathUsageException.java @@ -0,0 +1,25 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.query.sqm; + +import org.hibernate.query.SemanticException; + +/** + * Indicates an attempt to use an SqmPath in an unsupported manner - e.g., an + * attempt to de-reference a basic value + * + * @author Steve Ebersole + */ +public class IllegalPathUsageException extends SemanticException { + public IllegalPathUsageException(String message) { + super( message ); + } + + public IllegalPathUsageException(String message, Exception cause) { + super( message, cause ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java index baf026d6ae..63172425c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmPathSource.java @@ -6,10 +6,10 @@ */ package org.hibernate.query.sqm; +import java.util.Locale; import javax.persistence.metamodel.Bindable; import org.hibernate.metamodel.model.domain.DomainType; -import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -35,12 +35,31 @@ public interface SqmPathSource extends SqmExpressable, Bindable { */ DomainType getSqmPathType(); - SqmPathSource findSubPathSource(String name); + /** + * Find a SqmPathSource by name relative to this source. + * + * @throws IllegalPathUsageException to indicate that this source cannot be de-referenced + */ + SqmPathSource findSubPathSource(String name) throws IllegalPathUsageException; /** * Create an SQM path for this source relative to the given left-hand side */ SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState); - X sqmAs(Class type); + default X sqmAs(Class targetType) { + if ( targetType.isInstance( this ) ) { + //noinspection unchecked + return (X) this; + } + + throw new IllegalArgumentException( + String.format( + Locale.ROOT, + "`%s` cannot be treated as `%s`", + getClass().getName(), + targetType.getName() + ) + ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmQuerySource.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmQuerySource.java index 71ef3890f6..b3c77f76e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmQuerySource.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/SqmQuerySource.java @@ -7,6 +7,10 @@ package org.hibernate.query.sqm; /** + * Informational - used to identify the source of an SQM statement. + * + * @see org.hibernate.query.sqm.tree.SqmStatement#getQuerySource + * * @author Steve Ebersole */ public enum SqmQuerySource { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java index 5a2c343c19..574e588a56 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownEntityException.java @@ -13,7 +13,8 @@ import org.hibernate.query.SemanticException; *

* NOTE : JPA generally requires this to be reported as the far less useful * IllegalArgumentException. - * todo : account for this in the "exception conversion" handling + * + * todo (6.0) : account for this in the "exception conversion" handling * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java index bfb6acb8b7..88febbdab1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java @@ -12,6 +12,10 @@ import org.hibernate.query.SemanticException; import org.hibernate.query.sqm.tree.domain.SqmPath; /** + * + * + * todo (6.0) : account for this in the "exception conversion" handling + * * @author Steve Ebersole */ public class UnknownPathException extends SemanticException { @@ -21,7 +25,7 @@ public class UnknownPathException extends SemanticException { Locale.ROOT, "Could not resolve path `%s` relative to %s (%s)", name, - base.getReferencedPathSource().getNavigableType().getJavaTypeDescriptor().getTypeName(), + base.getReferencedPathSource().getSqmPathType().getTypeName(), base.getNavigablePath().getFullPath() ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSemanticQueryWalker.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSemanticQueryWalker.java index 659f6bc1ab..9797a2a3d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSemanticQueryWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSemanticQueryWalker.java @@ -6,8 +6,6 @@ */ package org.hibernate.query.sqm.consume.spi; -import java.lang.reflect.Field; - import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; @@ -28,11 +26,13 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched; import org.hibernate.query.sqm.tree.expression.SqmCaseSimple; import org.hibernate.query.sqm.tree.expression.SqmCollectionSize; import org.hibernate.query.sqm.tree.expression.SqmCriteriaParameter; +import org.hibernate.query.sqm.tree.expression.SqmEntityType; +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.SqmLiteral; import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType; import org.hibernate.query.sqm.tree.expression.SqmNamedParameter; -import org.hibernate.query.sqm.tree.expression.SqmEntityType; import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter; import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression; import org.hibernate.query.sqm.tree.expression.SqmTuple; @@ -40,6 +40,7 @@ import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation; import org.hibernate.query.sqm.tree.expression.function.SqmCastTarget; import org.hibernate.query.sqm.tree.expression.function.SqmDistinct; import org.hibernate.query.sqm.tree.expression.function.SqmExtractUnit; +import org.hibernate.query.sqm.tree.expression.function.SqmFunction; import org.hibernate.query.sqm.tree.expression.function.SqmStar; import org.hibernate.query.sqm.tree.expression.function.SqmTrimSpecification; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; @@ -49,18 +50,18 @@ import org.hibernate.query.sqm.tree.from.SqmFromClause; import org.hibernate.query.sqm.tree.from.SqmJoin; import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement; +import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate; import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate; import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate; import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate; import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate; import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate; import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate; -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.SqmGroupedPredicate; -import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate; -import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate; import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate; import org.hibernate.query.sqm.tree.predicate.SqmWhereClause; import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation; @@ -77,7 +78,6 @@ import org.hibernate.query.sqm.tree.update.SqmAssignment; import org.hibernate.query.sqm.tree.update.SqmSetClause; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.service.ServiceRegistry; -import org.hibernate.query.sqm.tree.expression.function.SqmFunction; /** * @author Steve Ebersole @@ -535,12 +535,12 @@ public class BaseSemanticQueryWalker implements SemanticQueryWalker { } @Override - public T visitFullyQualifiedEnum(Enum value) { + public T visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) { throw new UnsupportedOperationException( "Not supported" ); } @Override - public T visitFullyQualifiedField(Field field) { + public T visitFieldLiteral(SqmFieldLiteral sqmFieldLiteral) { throw new UnsupportedOperationException( "Not supported" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSqmToSqlAstConverter.java index 0ab5c6da41..b7f508e13e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/BaseSqmToSqlAstConverter.java @@ -18,15 +18,13 @@ import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.graph.spi.GraphImplementor; +import org.hibernate.internal.util.NullnessHelper; import org.hibernate.internal.util.collections.Stack; import org.hibernate.internal.util.collections.StandardStack; -import org.hibernate.metamodel.model.mapping.spi.EmbeddedValuedNavigable; -import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor; -import org.hibernate.metamodel.model.mapping.spi.NavigableContainer; +import org.hibernate.metamodel.model.domain.AllowableParameterType; import org.hibernate.query.BinaryArithmeticOperator; import org.hibernate.query.UnaryArithmeticOperator; import org.hibernate.query.internal.QueryHelper; -import org.hibernate.query.spi.ComparisonOperator; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; @@ -79,64 +77,25 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.JoinType; -import org.hibernate.sql.ast.produce.internal.SqlAstQuerySpecProcessingStateImpl; -import org.hibernate.sql.ast.produce.metamodel.spi.BasicValuedExpressableType; -import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType; -import org.hibernate.sql.ast.produce.metamodel.spi.SqlAliasBaseGenerator; -import org.hibernate.sql.ast.produce.spi.FromClauseAccess; -import org.hibernate.sql.ast.produce.spi.FromClauseIndex; -import org.hibernate.sql.ast.produce.spi.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.query.sqm.tree.expression.function.SqmFunction; -import org.hibernate.sql.ast.produce.spi.SqlAstProcessingState; -import org.hibernate.sql.ast.produce.spi.SqlAstQuerySpecProcessingState; -import org.hibernate.sql.ast.produce.spi.SqlExpressionResolver; -import org.hibernate.sql.ast.produce.spi.TableGroupJoinProducer; -import org.hibernate.sql.ast.produce.sqm.spi.Callback; -import org.hibernate.sql.ast.produce.sqm.spi.JdbcParameterBySqmParameterAccess; -import org.hibernate.sql.ast.produce.sqm.spi.SqmExpressionInterpretation; -import org.hibernate.sql.ast.produce.sqm.spi.SqmSelectToSqlAstConverter; -import org.hibernate.sql.ast.produce.sqm.spi.SqmToSqlAstConverter; +import org.hibernate.sql.ast.spi.SqlAstProcessingState; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; -import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; -import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression; -import org.hibernate.sql.ast.tree.expression.CastTarget; -import org.hibernate.sql.ast.tree.expression.Distinct; import org.hibernate.sql.ast.tree.expression.Expression; -import org.hibernate.sql.ast.tree.expression.ExtractUnit; -import org.hibernate.sql.ast.tree.expression.QueryLiteral; import org.hibernate.sql.ast.tree.expression.SqlTuple; -import org.hibernate.sql.ast.tree.expression.Star; -import org.hibernate.sql.ast.tree.expression.SubQuery; -import org.hibernate.sql.ast.tree.expression.TrimSpecification; -import org.hibernate.sql.ast.tree.expression.UnaryOperation; -import org.hibernate.sql.ast.tree.expression.domain.BasicValuedNavigableReference; -import org.hibernate.sql.ast.tree.expression.domain.EmbeddableValuedNavigableReference; -import org.hibernate.sql.ast.tree.expression.domain.EntityValuedNavigableReference; -import org.hibernate.sql.ast.tree.expression.domain.NavigableReference; -import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.from.TableGroupJoin; -import org.hibernate.sql.ast.tree.predicate.BetweenPredicate; -import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; -import org.hibernate.sql.ast.tree.predicate.GroupedPredicate; -import org.hibernate.sql.ast.tree.predicate.InListPredicate; -import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate; import org.hibernate.sql.ast.tree.predicate.Junction; -import org.hibernate.sql.ast.tree.predicate.LikePredicate; -import org.hibernate.sql.ast.tree.predicate.NegatedPredicate; -import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectClause; import org.hibernate.sql.ast.tree.select.SelectStatement; -import org.hibernate.sql.ast.tree.sort.SortSpecification; -import org.hibernate.sql.exec.internal.JdbcParametersImpl; -import org.hibernate.sql.exec.internal.StandardJdbcParameterImpl; +import org.hibernate.sql.ast.tree.select.SortSpecification; import org.hibernate.sql.exec.spi.JdbcParameter; import org.hibernate.sql.exec.spi.JdbcParameters; import org.hibernate.sql.results.spi.Fetch; import org.hibernate.sql.results.spi.FetchParent; -import org.hibernate.type.spi.StandardSpiBasicTypes; +import org.hibernate.type.StandardBasicTypes; import org.jboss.logging.Logger; @@ -176,7 +135,7 @@ public abstract class BaseSqmToSqlAstConverter private final Stack processingStateStack = new StandardStack<>(); private final Stack currentClauseStack = new StandardStack<>(); - private final Stack shallownessStack = new StandardStack<>( SqmSelectToSqlAstConverter.Shallowness.NONE ); + private final Stack shallownessStack = new StandardStack<>( Shallowness.NONE ); public BaseSqmToSqlAstConverter( SqlAstCreationContext creationContext, @@ -223,7 +182,7 @@ public abstract class BaseSqmToSqlAstConverter } @Override - public SqlAliasBaseGenerator getSqlAliasBaseGenerator() { + public SqlAliasBaseManager getSqlAliasBaseManager() { return sqlAliasBaseManager; } @@ -643,7 +602,8 @@ public abstract class BaseSqmToSqlAstConverter jdbcParamsBySqmParam.put( sqmParameter, jdbcParametersForSqm ); if ( jdbcParametersForSqm.size() > 1 ) { - return new SqlTuple( jdbcParametersForSqm, sqmParameter.getNodeType() ); + //noinspection unchecked + return new SqlTuple( (List) jdbcParametersForSqm ); } else { return jdbcParametersForSqm.get( 0 ); @@ -656,11 +616,17 @@ public abstract class BaseSqmToSqlAstConverter if ( expressableType == null ) { final QueryParameterImplementor queryParameter = domainParameterXref.getQueryParameter( expression ); final QueryParameterBinding binding = domainParameterBindings.getBinding( queryParameter ); - expressableType = QueryHelper.determineParameterType( binding, queryParameter, creationContext.getDomainModel().getTypeConfiguration() ); + expressableType = getCreationContext().getDomainModel().resolveQueryParameterType( + NullnessHelper.coalesce( + binding.getBindType(), + queryParameter.getHibernateType(), + expression.getAnticipatedType() + ).getJavaType() + ); if ( expressableType == null ) { log.debugf( "Could not determine ExpressableType for parameter [%s], falling back to Object-handling", expression ); - expressableType = StandardSpiBasicTypes.OBJECT_TYPE; + expressableType = StandardBasicTypes.OBJECT_TYPE; } expression.applyInferableType( expressableType ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/Callback.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/Callback.java new file mode 100644 index 0000000000..e6190f7e00 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/Callback.java @@ -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.sqm.consume.spi; + +import org.hibernate.loader.spi.AfterLoadAction; + +/** + * Callback to allow SQM interpretation to trigger certain things within ORM. See the current + * {@link AfterLoadAction} javadocs for details. Specifically this would + * encompass things like follow-on locking, follow-on fetching, etc. + * + * @author Steve Ebersole + */ +public interface Callback { + void registerAfterLoadAction(AfterLoadAction afterLoadAction); +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/JdbcParameterBySqmParameterAccess.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/JdbcParameterBySqmParameterAccess.java new file mode 100644 index 0000000000..6de2c69d45 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/JdbcParameterBySqmParameterAccess.java @@ -0,0 +1,25 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.query.sqm.consume.spi; + +import java.util.List; +import java.util.Map; + +import org.hibernate.query.sqm.tree.expression.SqmParameter; +import org.hibernate.sql.exec.spi.JdbcParameter; + +/** + * Access to the mapping between an SqmParameter and all of its JDBC parameters + * + * @author Steve Ebersole + */ +public interface JdbcParameterBySqmParameterAccess { + /** + * The mapping between an SqmParameter and all of its JDBC parameters + */ + Map> getJdbcParamsBySqmParam(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SemanticQueryWalker.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SemanticQueryWalker.java index 63a0a5a35d..4880efa00d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SemanticQueryWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SemanticQueryWalker.java @@ -6,8 +6,6 @@ */ package org.hibernate.query.sqm.consume.spi; -import java.lang.reflect.Field; - import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; @@ -27,13 +25,13 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched; import org.hibernate.query.sqm.tree.expression.SqmCaseSimple; import org.hibernate.query.sqm.tree.expression.SqmCollectionSize; import org.hibernate.query.sqm.tree.expression.SqmCriteriaParameter; +import org.hibernate.query.sqm.tree.expression.SqmEntityType; 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.SqmLiteral; import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType; import org.hibernate.query.sqm.tree.expression.SqmNamedParameter; -import org.hibernate.query.sqm.tree.expression.SqmEntityType; import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter; import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression; import org.hibernate.query.sqm.tree.expression.SqmTuple; @@ -41,6 +39,7 @@ import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation; import org.hibernate.query.sqm.tree.expression.function.SqmCastTarget; import org.hibernate.query.sqm.tree.expression.function.SqmDistinct; import org.hibernate.query.sqm.tree.expression.function.SqmExtractUnit; +import org.hibernate.query.sqm.tree.expression.function.SqmFunction; import org.hibernate.query.sqm.tree.expression.function.SqmStar; import org.hibernate.query.sqm.tree.expression.function.SqmTrimSpecification; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; @@ -49,18 +48,18 @@ import org.hibernate.query.sqm.tree.from.SqmEntityJoin; import org.hibernate.query.sqm.tree.from.SqmFromClause; import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement; +import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate; import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate; import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmGroupedPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate; +import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate; import org.hibernate.query.sqm.tree.predicate.SqmLikePredicate; import org.hibernate.query.sqm.tree.predicate.SqmMemberOfPredicate; import org.hibernate.query.sqm.tree.predicate.SqmNegatedPredicate; import org.hibernate.query.sqm.tree.predicate.SqmNullnessPredicate; -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.SqmGroupedPredicate; -import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate; -import org.hibernate.query.sqm.tree.predicate.SqmInSubQueryPredicate; import org.hibernate.query.sqm.tree.predicate.SqmOrPredicate; import org.hibernate.query.sqm.tree.predicate.SqmWhereClause; import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation; @@ -77,7 +76,6 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery; import org.hibernate.query.sqm.tree.update.SqmAssignment; import org.hibernate.query.sqm.tree.update.SqmSetClause; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; -import org.hibernate.query.sqm.tree.expression.function.SqmFunction; /** * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmExpressionInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmExpressionInterpretation.java new file mode 100644 index 0000000000..58c6285855 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmExpressionInterpretation.java @@ -0,0 +1,29 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.query.sqm.consume.spi; + +import org.hibernate.sql.ast.spi.SqlAstCreationState; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.results.spi.DomainResultProducer; + +/** + * The interpretation of an SqmExpression as part of the SQM -> SQL conversion. + * + * Allows multi-column navigable references to be used anywhere a (SqlExpression) + * can be. The trick is to properly define methods on this interface for how the + * thing should be rendered into the SQL AST. Access to the domain type descriptor + * also allows consumers to find out information about the + * + * @author Steve Ebersole + */ +public interface SqmExpressionInterpretation extends DomainResultProducer { + ExpressableType getExpressableType(); + + default Expression toSqlExpression(SqlAstCreationState sqlAstCreationState) { + return (Expression) this; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmToSqlAstConverter.java index 97c8c39d39..9f3041726e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/consume/spi/SqmToSqlAstConverter.java @@ -6,11 +6,13 @@ */ package org.hibernate.query.sqm.consume.spi; +import org.hibernate.sql.ast.spi.SqlAstCreationState; + /** - * Specialized SemanticQueryWalker (SQM visitor) for producing - * SQL AST + * Specialized SemanticQueryWalker (SQM visitor) for producing SQL AST. * * @author Steve Ebersole */ +@SuppressWarnings("WeakerAccess") public interface SqmToSqlAstConverter extends SemanticQueryWalker, SqlAstCreationState { } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index ef9be13a7f..3f01788c83 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -170,6 +170,11 @@ public class QuerySqmImpl return getSession().getFactory(); } + @Override + public QueryParameterBindings getParameterBindings() { + return parameterBindings; + } + private boolean isSelect() { return sqmStatement instanceof SqmSelectStatement; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index 569ec01d80..5f8d67831c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -371,6 +371,47 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder { ); } + @Override + public SqmTuple tuple(Class tupleType, JpaExpression... expressions) { + //noinspection unchecked + return new SqmTuple( + (List) asList( expressions ), +// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ), + this + ); + } + + @Override + public SqmTuple tuple(Class tupleType, List> expressions) { + //noinspection unchecked + return new SqmTuple( + (List) expressions, +// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ), + this + ); + } + + @Override + public SqmTuple tuple(DomainType tupleType, JpaExpression... expressions) { + //noinspection unchecked + return new SqmTuple( + (List) asList( expressions ), + tupleType, + this + ); + } + + @Override + public SqmTuple tuple( + DomainType tupleType, List> expressions) { + //noinspection unchecked + return new SqmTuple( + new ArrayList<>((List) expressions), + tupleType, + this + ); + } + @Override public JpaCompoundSelection array(Selection[] selections) { //noinspection unchecked @@ -1228,47 +1269,6 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder { return new SqmCaseSearched<>( this ); } - @Override - public SqmTuple tuple(Class tupleType, JpaExpression... expressions) { - //noinspection unchecked - return new SqmTuple( - (List) asList( expressions ), -// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ), - this - ); - } - - @Override - public SqmTuple tuple(Class tupleType, List> expressions) { - //noinspection unchecked - return new SqmTuple( - (List) expressions, -// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ), - this - ); - } - - @Override - public SqmTuple tuple(DomainType tupleType, JpaExpression... expressions) { - //noinspection unchecked - return new SqmTuple( - (List) asList( expressions ), - tupleType, - this - ); - } - - @Override - public SqmTuple tuple( - DomainType tupleType, List> expressions) { - //noinspection unchecked - return new SqmTuple( - new ArrayList<>((List) expressions), - tupleType, - this - ); - } - @Override public > SqmExpression mapSize(JpaExpression mapExpression) { return new SqmCollectionSize( (SqmPath) mapExpression, this ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmIdSelectGenerator.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmIdSelectGenerator.java index 765420631c..15f481c103 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmIdSelectGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/SqmIdSelectGenerator.java @@ -11,8 +11,8 @@ import org.hibernate.internal.util.collections.Stack; import org.hibernate.internal.util.collections.StandardStack; import org.hibernate.metamodel.model.mapping.EntityTypeDescriptor; import org.hibernate.query.sqm.NodeBuilder; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; -import org.hibernate.query.sqm.produce.SqmQuerySpecCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmQuerySpecCreationProcessingState; import org.hibernate.query.sqm.produce.spi.ImplicitAliasGenerator; import org.hibernate.query.sqm.produce.spi.SqmCreationContext; import org.hibernate.query.sqm.produce.spi.SqmCreationOptions; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationHelper.java index f50cce70db..9b4b66f874 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationHelper.java @@ -7,13 +7,7 @@ package org.hibernate.query.sqm.produce; import org.hibernate.query.NavigablePath; -import org.hibernate.query.sqm.SqmJoinable; -import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.produce.spi.SqmCreationState; -import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.domain.SqmPath; -import org.hibernate.query.sqm.tree.from.SqmFrom; -import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; /** * @author Steve Ebersole @@ -45,56 +39,4 @@ public class SqmCreationHelper { private SqmCreationHelper() { } - public static void resolveAsLhs( - SqmPath lhs, - SqmPath processingPath, - SqmPathSource subNavigable, - boolean isSubRefTerminal, - SqmCreationState creationState) { - SqmTreeCreationLogger.LOGGER.tracef( - "`SqmEntityValuedSimplePath#prepareForSubNavigableReference` : %s -> %s", - lhs == null ? "[null]" : lhs.getNavigablePath().getFullPath(), - subNavigable - ); - - if ( lhs == null ) { - // this should mean that `processingPath` is an `SqmRoot` and really does not need resolution. - // - just skip it - return; - } - - final SqmCreationProcessingState processingState = creationState.getProcessingStateStack().getCurrent(); - - final SqmFrom lhsFrom; - if ( lhs instanceof SqmFrom ) { - lhsFrom = (SqmFrom) lhs; - } - else { - lhs.prepareForSubNavigableReference( processingPath.getReferencedPathSource(), false, creationState ); - - // now we should be able to access the SqmFrom node for the `lhs`... - lhsFrom = processingState.getPathRegistry().findFromByPath( lhs.getNavigablePath() ); - } - - if ( subNavigable instanceof EntityIdentifier && isSubRefTerminal ) { - // do not create the join if the subNavigable reference is an entity identifier and is the path terminal - // e.g., `select p.address.id from Person p ...` - return; - } - - // create the join if not already - - final SqmFrom existingJoin = processingState.getPathRegistry().findFromByPath( processingPath.getNavigablePath() ); - if ( existingJoin == null ) { - final SqmAttributeJoin sqmJoin = ( (SqmJoinable) processingPath.getReferencedPathSource() ).createSqmJoin( - lhsFrom, - SqmJoinType.INNER, - null, - false, - creationState - ); - lhsFrom.addSqmJoin( sqmJoin ); - processingState.getPathRegistry().register( sqmJoin ); - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/internal/SelfRenderingFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/internal/SelfRenderingFunctionSqlAstExpression.java index 090d946fea..3bacf1d105 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/internal/SelfRenderingFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/internal/SelfRenderingFunctionSqlAstExpression.java @@ -26,7 +26,7 @@ import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.DomainResultCreationState; import org.hibernate.sql.results.spi.DomainResultProducer; import org.hibernate.sql.results.spi.Selectable; -import org.hibernate.sql.results.spi.SqlSelection; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.type.descriptor.java.spi.BasicJavaDescriptor; import org.hibernate.type.spi.TypeConfiguration; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmCreationProcessingStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmCreationProcessingStateImpl.java index 765ce35ebe..a31c2a1520 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmCreationProcessingStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmCreationProcessingStateImpl.java @@ -7,7 +7,7 @@ package org.hibernate.query.sqm.produce.internal; import org.hibernate.query.hql.internal.SqmPathRegistryImpl; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.hql.spi.SqmPathRegistry; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.SqmQuery; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmQuerySpecCreationProcessingStateStandardImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmQuerySpecCreationProcessingStateStandardImpl.java index f2d9467aec..0a3d062abe 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmQuerySpecCreationProcessingStateStandardImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/internal/SqmQuerySpecCreationProcessingStateStandardImpl.java @@ -6,8 +6,8 @@ */ package org.hibernate.query.sqm.produce.internal; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; -import org.hibernate.query.sqm.produce.SqmQuerySpecCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmQuerySpecCreationProcessingState; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.select.SqmSelectQuery; import org.hibernate.query.sqm.tree.select.SqmSelection; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationProcessingState.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationProcessingState.java similarity index 84% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationProcessingState.java rename to hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationProcessingState.java index 056d3065ed..d36a667367 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmCreationProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationProcessingState.java @@ -4,11 +4,10 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html */ -package org.hibernate.query.sqm.produce; +package org.hibernate.query.sqm.produce.spi; import org.hibernate.Incubating; import org.hibernate.query.hql.spi.SqmPathRegistry; -import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.SqmQuery; /** @@ -28,6 +27,10 @@ public interface SqmCreationProcessingState { */ SqmCreationProcessingState getParentProcessingState(); + /** + * Access to the query currently being processed. This should be generally considered + * an inflight model - we are still in the process of creating the SQM + */ SqmQuery getProcessingQuery(); /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationState.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationState.java index a5b329fae0..62b3e5d7c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmCreationState.java @@ -8,7 +8,6 @@ package org.hibernate.query.sqm.produce.spi; import org.hibernate.Incubating; import org.hibernate.internal.util.collections.Stack; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; /** * Models the state pertaining to the creation of a single SQM. diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmQuerySpecCreationProcessingState.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmQuerySpecCreationProcessingState.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmQuerySpecCreationProcessingState.java rename to hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmQuerySpecCreationProcessingState.java index 8c44071a27..0eafefca95 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/SqmQuerySpecCreationProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/produce/spi/SqmQuerySpecCreationProcessingState.java @@ -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.query.sqm.produce; +package org.hibernate.query.sqm.produce.spi; import org.hibernate.Incubating; import org.hibernate.query.sqm.tree.select.SqmSelectQuery; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java index fecb2dae2d..ea8c405863 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java @@ -20,6 +20,7 @@ import org.hibernate.metamodel.model.domain.MapPersistentAttribute; import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.query.NavigablePath; +import org.hibernate.query.sqm.IllegalPathUsageException; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.produce.spi.SqmCreationState; @@ -119,12 +120,7 @@ public abstract class AbstractSqmPath extends AbstractSqmExpression implem @Override public SqmPathSource findSubPathSource(String name) { - throw new UnsupportedOperationException( "Entity discriminator cannot be de-referenced" ); - } - - @Override - public DomainType sqmAs(Class type) { - return null; + throw new IllegalPathUsageException( "Entity discriminator cannot be de-referenced" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBagJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBagJoin.java index 614fe8e3ab..74b5fa2a13 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBagJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmBagJoin.java @@ -22,7 +22,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.criteria.JpaSubQuery; import org.hibernate.query.PathException; import org.hibernate.query.sqm.NodeBuilder; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEntityValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEntityValuedSimplePath.java index c5d07bd4ea..9833415dd4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEntityValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmEntityValuedSimplePath.java @@ -9,11 +9,10 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.NavigablePath; import org.hibernate.query.PathException; +import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker; -import org.hibernate.query.sqm.produce.SqmCreationHelper; -import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.sqm.produce.spi.SqmCreationState; /** @@ -36,8 +35,6 @@ public class SqmEntityValuedSimplePath extends AbstractSqmSimplePath { final SqmPathSource referencedPathSource = getReferencedPathSource(); final SqmPathSource subPathSource = referencedPathSource.findSubPathSource( name ); - prepareForSubNavigableReference( subPathSource, isTerminal, creationState ); - assert getLhs() == null || creationState.getProcessingStateStack() .getCurrent() .getPathRegistry() @@ -52,29 +49,6 @@ public class SqmEntityValuedSimplePath extends AbstractSqmSimplePath { return walker.visitEntityValuedPath( this ); } - private boolean dereferenced; - - @Override - public void prepareForSubNavigableReference( - SqmPathSource subNavigable, - boolean isSubReferenceTerminal, - SqmCreationState creationState) { - if ( dereferenced ) { - // nothing to do, already dereferenced - return; - } - - log.tracef( - "`SqmEntityValuedSimplePath#prepareForSubNavigableReference` : %s -> %s", - getNavigablePath().getFullPath(), - subNavigable.getPathName() - ); - - SqmCreationHelper.resolveAsLhs( getLhs(), this, subNavigable, isSubReferenceTerminal, creationState ); - - dereferenced = true; - } - @Override public EntityDomainType getNodeType() { //noinspection unchecked diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmListJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmListJoin.java index a6a65c07f7..d166164440 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmListJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmListJoin.java @@ -23,7 +23,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.criteria.JpaSubQuery; import org.hibernate.query.PathException; import org.hibernate.query.sqm.NodeBuilder; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapJoin.java index 54c409193d..c6a102ed99 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapJoin.java @@ -23,7 +23,7 @@ import org.hibernate.query.criteria.JpaSubQuery; import org.hibernate.query.PathException; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java index eb769b4e28..832127364c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java @@ -8,22 +8,20 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.NavigablePath; -import org.hibernate.query.criteria.JpaPath; import org.hibernate.query.PathException; -import org.hibernate.query.sqm.ParsingException; import org.hibernate.query.SemanticException; +import org.hibernate.query.criteria.JpaPath; +import org.hibernate.query.hql.spi.SemanticPathPart; +import org.hibernate.query.sqm.ParsingException; import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.produce.SqmCreationHelper; -import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** - * Models a reference to a part of the application's domain model (a Navigable) - * as part of an SQM tree. + * Models a reference to a part of the application's domain model as part of an SQM tree. * * This correlates roughly to the JPA Criteria notion of Path, hence the name. * @@ -49,6 +47,9 @@ public interface SqmPath extends SqmExpression, SemanticPathPart, JpaPath< */ String getExplicitAlias(); + /** + * Set the explicit alias for this path + */ void setExplicitAlias(String explicitAlias); /** @@ -57,6 +58,9 @@ public interface SqmPath extends SqmExpression, SemanticPathPart, JpaPath< */ SqmPath getLhs(); + /** + * This node's type is its "referenced path source" + */ @Override SqmPathSource getNodeType(); @@ -92,95 +96,4 @@ public interface SqmPath extends SqmExpression, SemanticPathPart, JpaPath< SqmCreationState creationState) { throw new SemanticException( "Non-plural path [" + getNavigablePath() + "] cannot be index-accessed" ); } - - /** - * Perform any preparations needed to process the named Navigable. Create joins? - * - * This should equate to resolution of implicit joins. Given - * `select p.address.city from Person p ....`, e.g., we'd end up with the following: - * - * 1) Because we process the from-clause first, `Person p` is already available as an - * SqmRoot with NavigablePath[Person(p)] - * 2) As we process the select-clause, the `p.address.city` dot-ident sequence is processed - * by the registered `DotIdentifierConsumer` - * - * 1) the first part (`p`) is resolved, internally, as the registered SqmRoot as an alias - * which is tracked there as its "current `SemanticPathPart`" - * 2) each "continuation" (here `address` and then `city`) is handled by applying that - * name to the "current `SemanticPathPart`", assigning its result back as the new - * "current `SemanticPathPart`" - * - * 1) `address` is resolved against SqmRoot, producing a `SqmEmbeddedValuedSimplePath` - * with NavigablePath[Person(p).address]. That is registered in the PathRegistry - * in `#sqmPathMap`, but not (yet) in `#sqmFromPath`. - * 2) `city` is resolved against the SqmEmbeddedValuedSimplePath(NavigablePath[Person(p).address]). - * This triggers a few things: - * - * 1) SqmEmbeddedValuedSimplePath( Person(p).address ) is given a - * chance to prepare itself to be used as the LHS via this `#prepareForSubNavigableReference` - * method. Here, we use that opportunity to create the implicit SqmNavigableJoin for - * the same `Person(p).address` path. We register this join form with the PathRegistry - * which "over-writes" the previous `SqmEmbeddedValuedSimplePath` registration - * 2) Processing `city` produces a `SqmBasicValuedSimplePath( Person(p).address.city )` - * which is registered in the PathRegistry, again just in `#sqmPathMap`, but not (yet) - * in `#sqmFromPath` - * - * At this point processing would return from `DotIdentifierConsumer` back to `SemanticQueryBuilder` - * where we call `DotIdentifierConsumer#getConsumedPart` to get the last "current part" - * `SqmBasicValuedSimplePath( Person(p).address.city )` as the result for the fully resolved - * dot-ident-sequence - * - * todo (6.0) : ideally we'd delay this until SQM -> SQL AST conversion : criteria-as-SQM - */ - default void prepareForSubNavigableReference( - SqmPathSource subNavigable, - boolean isSubReferenceTerminal, - SqmCreationState creationState) { - SqmCreationHelper.resolveAsLhs( getLhs(), this, subNavigable, isSubReferenceTerminal, creationState ); - } - -// /** -// * Treat this path as the given type. "Cast it" to the target type. -// * -// * May throw an exception if the Path is not treatable as the requested type. -// * -// * Also recognizes any {@link Navigable} target type and applies it to the -// * {@link #getReferencedPathSource()}. -// * -// * @apiNote This is very different from JPA's {@link #as} (and variants like -// * {@link #asInteger()}, etc) which are equivalent to SQL CAST function calls. -// * -// * @return The "casted" reference -// */ -// @SuppressWarnings("unchecked") -// default X sqmAs(Class targetType) { -// if ( targetType.isInstance( this ) ) { -// return (X) this; -// } -// -// if ( getReferencedPathSource().getSqmPathType() -// .getExpressableJavaTypeDescriptor() -// .getJavaType() -// .isAssignableFrom( targetType ) ) { -// return (X) ( (Navigable) getReferencedPathSource() ).as( targetType ); -// } -// -// throw new IllegalArgumentException( -// String.format( -// Locale.ROOT, -// "`%s` cannot be treated as `%s`", -// getClass().getName(), -// targetType.getName() -// ) -// ); -// } -// -// default X sqmAs(Class targetType, Supplier exceptionSupplier) { -// try { -// return sqmAs( targetType ); -// } -// catch (IllegalArgumentException e) { -// throw exceptionSupplier.get(); -// } -// } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPolymorphicRootDescriptor.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPolymorphicRootDescriptor.java index d9430c874c..a9565030f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPolymorphicRootDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPolymorphicRootDescriptor.java @@ -360,11 +360,6 @@ public class SqmPolymorphicRootDescriptor implements EntityDomainType { throw new UnsupportedOperationException(); } - @Override - public X sqmAs(Class type) { - throw new NotYetImplementedFor6Exception(); - } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Unsupported operations diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSetJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSetJoin.java index 80c07e91df..060d7a51b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSetJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSetJoin.java @@ -22,7 +22,7 @@ import org.hibernate.query.criteria.JpaSetJoin; import org.hibernate.query.criteria.JpaSubQuery; import org.hibernate.query.PathException; import org.hibernate.query.sqm.NodeBuilder; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java index 99927b8a4a..db38795021 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java @@ -12,7 +12,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; import org.hibernate.query.PathException; import org.hibernate.query.sqm.NodeBuilder; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java index f5eff3760a..ff0ee6a1ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.BagPersistentAttribute; import org.hibernate.metamodel.model.domain.EntityDomainType; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java index c6ffc349b0..46534c2233 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.ListPersistentAttribute; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java index 1b0ee71ac7..d79c546909 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java @@ -7,7 +7,7 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java index 75a9d1ce09..9524e374f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.SetPersistentAttribute; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java index 4543ae4b8c..58b71cb17d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain; import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.SingularPersistentAttribute; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java index 6b8da88570..7deadc76e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java @@ -22,8 +22,8 @@ import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker; import org.hibernate.query.sqm.produce.spi.SqmCreationState; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; +import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; -import org.hibernate.type.descriptor.java.spi.EnumJavaDescriptor; /** * Specialized SQM literal defined by an enum reference. E.g. @@ -33,7 +33,7 @@ import org.hibernate.type.descriptor.java.spi.EnumJavaDescriptor; */ public class SqmEnumLiteral implements SqmExpression, SqmExpressable, SemanticPathPart { private final Enum enumValue; - private final EnumJavaDescriptor referencedEnumTypeDescriptor; + private final EnumJavaTypeDescriptor referencedEnumTypeDescriptor; private final String enumValueName; private final NodeBuilder nodeBuilder; @@ -41,7 +41,7 @@ public class SqmEnumLiteral implements SqmExpression, SqmExpressable public SqmEnumLiteral( Enum enumValue, - EnumJavaDescriptor referencedEnumTypeDescriptor, + EnumJavaTypeDescriptor referencedEnumTypeDescriptor, String enumValueName, NodeBuilder nodeBuilder) { this.enumValue = enumValue; @@ -61,7 +61,7 @@ public class SqmEnumLiteral implements SqmExpression, SqmExpressable } @Override - public EnumJavaDescriptor getExpressableJavaTypeDescriptor() { + public EnumJavaTypeDescriptor getExpressableJavaTypeDescriptor() { return referencedEnumTypeDescriptor; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java index 1e871cd59e..c08d481db0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java @@ -15,18 +15,17 @@ import org.hibernate.query.criteria.JpaSelection; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker; +import org.hibernate.query.sqm.tree.select.SqmJpaCompoundSelection; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** * Models a tuple of values, generally defined as a series of values - * wrapped in parentheses, e.g. `(value1, value2, ..., valueN)` + * wrapped in parentheses, e.g. `(value1, value2, ..., valueN)`. * - * todo (6.0) : possibly a place to centralize how a tuple is handled via a - * special EmbeddedValuedExpressableType as the tuple's `#getNodeType` - * + - * it should honor `# + * Differs from {@link SqmJpaCompoundSelection} in that this node can be used + * anywhere in the SQM tree, whereas SqmJpaCompoundSelection is only valid + * in the SELECT clause per JPA * - * it could implement EmbeddedValuedExpressableType * @author Steve Ebersole */ public class SqmTuple extends AbstractSqmExpression implements JpaCompoundSelection { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmAttributeJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmAttributeJoin.java index 23407c55f5..1e5c70896f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmAttributeJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmAttributeJoin.java @@ -10,7 +10,7 @@ import org.hibernate.HibernateException; import org.hibernate.query.criteria.JpaFetch; import org.hibernate.query.criteria.JpaJoin; import org.hibernate.query.sqm.SqmPathSource; -import org.hibernate.query.sqm.produce.SqmCreationProcessingState; +import org.hibernate.query.sqm.produce.spi.SqmCreationProcessingState; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java index 827f81f169..4df3805363 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java @@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.select; import java.util.List; -import javax.persistence.metamodel.Type; +import javax.persistence.criteria.Selection; import org.hibernate.query.criteria.JpaCompoundSelection; import org.hibernate.query.criteria.JpaSelection; @@ -24,11 +24,36 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; * Models either a `Tuple` or `Object[]` selection as defined by the * JPA Criteria API. * + * @see org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder#tuple(Selection[]) + * @see javax.persistence.criteria.CriteriaBuilder#tuple(javax.persistence.criteria.Selection[]) + * + * @see org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder#array(Selection[]) + * @see javax.persistence.criteria.CriteriaBuilder#array(javax.persistence.criteria.Selection[]) + * + * @see org.hibernate.query.sqm.tree.expression.SqmTuple + * * @author Steve Ebersole */ public class SqmJpaCompoundSelection extends AbstractSqmExpression implements JpaCompoundSelection, SqmExpressable { + + // todo (6.0) : should this really be SqmExpressable? + // - seems like it ought to be limited to just `SqmSelectableNode`. + // otherwise why the distinction? why not just just re-use the same + // impl between this and `org.hibernate.query.sqm.tree.expression.SqmTuple`? + // Seems like either: + // a) this contract should not define support for being used out side the select clause, + // which would mean implementing `SqmSelectableNode`, but not `SqmExpressable` - so it + // would not be usable as a + // b) + // + // todo (6.0) : either way we need to make sure we should support whether "tuples" can be used "outside the select clause" + // - see `org.hibernate.jpa.spi.JpaCompliance#isJpaQueryComplianceEnabled` = the spec only defines + // support for using "compound selections" in the select clause. In most cases Hibernate + // can support using tuples in other clauses. If we keep the Easy way is to add a switch in creation of these + // whether `SqmJpaCompoundSelection` or `SqmTuple` is used based on `JpaCompliance#isJpaQueryComplianceEnabled` + private final List> selectableNodes; private final JavaTypeDescriptor javaTypeDescriptor; diff --git a/hibernate-core/src/main/java/org/hibernate/result/internal/OutputsImpl.java b/hibernate-core/src/main/java/org/hibernate/result/internal/OutputsImpl.java index f611b264b6..197b4c95fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/result/internal/OutputsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/result/internal/OutputsImpl.java @@ -16,7 +16,6 @@ import java.util.Set; import java.util.function.Supplier; import org.hibernate.JDBCException; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.loader.EntityAliases; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/Clause.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/Clause.java index 7f0b80a5be..aafe49f78a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/Clause.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/Clause.java @@ -39,6 +39,7 @@ public enum Clause { HAVING, ORDER, LIMIT, + OFFSET, CALL, /** diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreeCreationException.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreeCreationException.java new file mode 100644 index 0000000000..786e5c28d6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlTreeCreationException.java @@ -0,0 +1,24 @@ +/* + * 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; + +import org.hibernate.HibernateException; + +/** + * Base exception type for problems building a SQL tree. + * + * @author Steve Ebersole + */ +public class SqlTreeCreationException extends HibernateException { + public SqlTreeCreationException(String message) { + super( message ); + } + + public SqlTreeCreationException(String message, Throwable cause) { + super( message, cause ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/package-info.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/package-info.java new file mode 100644 index 0000000000..b1f1bfd825 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/package-info.java @@ -0,0 +1,11 @@ +/* + * 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 defining a SQL AST for use in creating and executing various JDBC operations + */ +package org.hibernate.sql.ast; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBase.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBase.java new file mode 100644 index 0000000000..49cc63e42a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBase.java @@ -0,0 +1,24 @@ +/* + * 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; + +/** + * A generator for new incremental SQL aliases based on a stem + * + * @author Steve Ebersole + */ +public interface SqlAliasBase { + /** + * The stem for unique alias generation + */ + String getAliasStem(); + + /** + * Generates a new alias based on the stem + */ + String generateNewAlias(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java new file mode 100644 index 0000000000..dcb05d232d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseManager.java @@ -0,0 +1,52 @@ +/* + * 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 java.util.HashMap; +import java.util.Map; + +/** + * Helper used in creating unique SQL table aliases for a SQL AST + * + * @author Steve Ebersole + */ +public class SqlAliasBaseManager { + // work dictionary used to map an acronym to the number of times it has been used. + private Map acronymCountMap = new HashMap<>(); + + public SqlAliasBase createSqlAliasBase(String stem) { + Integer acronymCount = acronymCountMap.get( stem ); + if ( acronymCount == null ) { + acronymCount = 0; + } + acronymCount++; + acronymCountMap.put( stem, acronymCount ); + + return new SqlAliasBaseImpl( stem + acronymCount ); + } + + private static class SqlAliasBaseImpl implements SqlAliasBase { + private final String stem; + private int aliasCount; + + SqlAliasBaseImpl(String stem) { + this.stem = stem; + } + + @Override + public String getAliasStem() { + return stem; + } + + @Override + public String generateNewAlias() { + synchronized ( this ) { + return stem + '_' + (aliasCount++); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAppender.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAppender.java new file mode 100644 index 0000000000..66c4ecbd3a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAppender.java @@ -0,0 +1,29 @@ +/* + * 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; + +/** + * Access to appending SQL fragments to an in-flight buffer + * + * @author Steve Ebersole + */ +public interface SqlAppender { + // todo (6.0) : add all the others sql keywords + String SELECT_KEYWORD = "select "; + String DISTINCT_KEYWORD = "distinct "; + String COMA_SEPARATOR = ", "; + String OPEN_PARENTHESIS = "("; + String CLOSE_PARENTHESIS = ")"; + String NO_SEPARATOR = ""; + String EMPTY_STRING_SEPARATOR = " "; + String FROM_KEYWORD = " from "; + + /** + * Add the passed fragment into the in-flight buffer + */ + void appendSql(String fragment); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java index 54343f713e..874595e2ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstCreationState.java @@ -11,6 +11,8 @@ import java.util.List; import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.graph.spi.GraphImplementor; +import org.hibernate.sql.results.spi.Fetch; +import org.hibernate.sql.results.spi.FetchParent; /** * @author Steve Ebersole @@ -24,7 +26,7 @@ public interface SqlAstCreationState { FromClauseAccess getFromClauseAccess(); - SqlAliasBaseGenerator getSqlAliasBaseGenerator(); + SqlAliasBaseManager getSqlAliasBaseManager(); default GraphImplementor getCurrentResultGraphNode() { throw new NotYetImplementedFor6Exception( getClass() ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java index b07bb0bca0..8ff4ca2f24 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstProcessingState.java @@ -17,5 +17,7 @@ public interface SqlAstProcessingState { SqlExpressionResolver getSqlExpressionResolver(); + + SqlAstCreationState getSqlAstCreationState(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTreeHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTreeHelper.java new file mode 100644 index 0000000000..97fb87f40d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstTreeHelper.java @@ -0,0 +1,54 @@ +/* + * 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.predicate.Junction; +import org.hibernate.sql.ast.tree.predicate.Predicate; + +/** + * @author Steve Ebersole + */ +public class SqlAstTreeHelper { + /** + * Singleton access + */ + public static final SqlAstTreeHelper INSTANCE = new SqlAstTreeHelper(); + + private SqlAstTreeHelper() { + } + + + public static Predicate combinePredicates(Predicate baseRestriction, Predicate incomingRestriction) { + if ( baseRestriction == null ) { + return incomingRestriction; + } + + final Junction combinedPredicate; + + if ( baseRestriction instanceof Junction ) { + final Junction junction = (Junction) baseRestriction; + if ( junction.isEmpty() ) { + return incomingRestriction; + } + + if ( junction.getNature() == Junction.Nature.CONJUNCTION ) { + combinedPredicate = junction; + } + else { + combinedPredicate = new Junction( Junction.Nature.CONJUNCTION ); + combinedPredicate.add( baseRestriction ); + } + } + else { + combinedPredicate = new Junction( Junction.Nature.CONJUNCTION ); + } + + combinedPredicate.add( incomingRestriction ); + + return combinedPredicate; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstWalker.java index def96a77cf..1e1f89f820 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAstWalker.java @@ -7,28 +7,15 @@ package org.hibernate.sql.ast.spi; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.sql.ast.produce.spi.SqlSelectionExpression; import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression; -import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression; -import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression; -import org.hibernate.sql.ast.tree.expression.CastTarget; import org.hibernate.sql.ast.tree.expression.ColumnReference; -import org.hibernate.sql.ast.tree.expression.Distinct; -import org.hibernate.sql.ast.tree.expression.ExtractUnit; -import org.hibernate.sql.ast.tree.expression.GenericParameter; -import org.hibernate.sql.ast.tree.expression.NamedParameter; -import org.hibernate.sql.ast.tree.expression.PositionalParameter; -import org.hibernate.sql.ast.tree.expression.QueryLiteral; +import org.hibernate.sql.ast.tree.expression.EntityTypeLiteral; +import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression; +import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression; import org.hibernate.sql.ast.tree.expression.SqlTuple; -import org.hibernate.sql.ast.tree.expression.Star; -import org.hibernate.sql.ast.tree.expression.TrimSpecification; -import org.hibernate.sql.ast.tree.expression.UnaryOperation; -import org.hibernate.sql.ast.tree.expression.domain.EntityTypeLiteral; import org.hibernate.sql.ast.tree.from.FromClause; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; -import org.hibernate.sql.ast.tree.from.TableReference; -import org.hibernate.sql.ast.tree.from.TableReferenceJoin; import org.hibernate.sql.ast.tree.predicate.BetweenPredicate; import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate; import org.hibernate.sql.ast.tree.predicate.FilterPredicate; @@ -42,9 +29,8 @@ import org.hibernate.sql.ast.tree.predicate.NullnessPredicate; import org.hibernate.sql.ast.tree.predicate.SelfRenderingPredicate; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectClause; -import org.hibernate.sql.ast.tree.sort.SortSpecification; +import org.hibernate.sql.ast.tree.select.SortSpecification; import org.hibernate.sql.ast.tree.update.Assignment; -import org.hibernate.sql.results.spi.SqlSelection; /** * @author Steve Ebersole diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java new file mode 100644 index 0000000000..5570bc4dd0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java @@ -0,0 +1,52 @@ +/* + * 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; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * Resolution of a SqlSelection reference for a given SqlSelectable. Some + * SqlSelectable are required to be qualified (e.g. a Column) - this is indicated + * by the QualifiableSqlSelectable sub-type. The NonQualifiableSqlSelectable + * sub-type indicates a SqlSelectable that does not require qualification (e.g. a + * literal). + *

+ * The point of this contract is to allow "unique-ing" of SqlSelectable references + * in a query to a single SqlSelection reference - effectively a caching of + * SqlSelection instances keyed by the SqlSelectable (+ qualifier when applicable) + * that it refers to. + * + * Note also that the returns can be a specialized Expression represented by + * {@link org.hibernate.sql.ast.tree.expression.SqlSelectionExpression} + * + * @author Steve Ebersole + */ +public interface SqlExpressionResolver { + /** + * Given a qualifier + a qualifiable SqlExpressable, resolve the + * (Sql)Expression reference. + */ + Expression resolveSqlExpression(ColumnReferenceQualifier qualifier, QualifiableSqlExpressable sqlSelectable); + + /** + * Given a SqlExpressable not needing to be qualified, resolve the + * (Sql)Expression reference. + */ + Expression resolveSqlExpression(NonQualifiableSqlExpressable sqlSelectable); + + /** + * Resolve the SqlSelection for the given expression + */ + SqlSelection resolveSqlSelection( + Expression expression, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration); + + SqlSelection emptySqlSelection(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelection.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelection.java similarity index 92% rename from hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelection.java rename to hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelection.java index 1c06130475..1800008c86 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelection.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelection.java @@ -4,14 +4,16 @@ * 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.results.spi; +package org.hibernate.sql.ast.spi; import java.util.function.Consumer; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.sql.ast.spi.SqlAstWalker; import org.hibernate.sql.exec.spi.JdbcValueExtractor; +import org.hibernate.sql.results.spi.JdbcValuesMappingDescriptor; +import org.hibernate.sql.results.spi.RowProcessingState; +import org.hibernate.sql.results.spi.SqlSelectionGroupNode; /** * Represents a selection at the SQL/JDBC level. Essentially made up of: diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelectionProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelectionProducer.java new file mode 100644 index 0000000000..f465144bd4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlSelectionProducer.java @@ -0,0 +1,24 @@ +/* + * 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.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * @author Steve Ebersole + */ +public interface SqlSelectionProducer { + /** + * Create a SqlSelection for the given JDBC ResultSet position + */ + SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/package-info.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/package-info.java index d4f4ab6748..532d92d836 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/package-info.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/package-info.java @@ -6,7 +6,6 @@ */ /** - * Package defining an AST for describing a SQL Statement, as well as - * for creating and consuming then + * Package defining support for creating and consuming SQL AST */ package org.hibernate.sql.ast.spi; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java new file mode 100644 index 0000000000..bad83827ff --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/MutationStatement.java @@ -0,0 +1,17 @@ +/* + * 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.tree; + +import org.hibernate.sql.ast.tree.predicate.PredicateContainer; + +/** + * Specialization of Statement for mutation (DML) statements + * + * @author Steve Ebersole + */ +public interface MutationStatement extends Statement { +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstNode.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstNode.java new file mode 100644 index 0000000000..12ed18057b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstNode.java @@ -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.tree; + +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * @author Steve Ebersole + */ +public interface SqlAstNode { + void accept(SqlAstWalker sqlTreeWalker); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstTreeLogger.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstTreeLogger.java new file mode 100644 index 0000000000..98844abfa4 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/SqlAstTreeLogger.java @@ -0,0 +1,31 @@ +/* + * 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.tree; + +import org.jboss.logging.BasicLogger; +import org.jboss.logging.Logger; +import org.jboss.logging.annotations.MessageLogger; +import org.jboss.logging.annotations.ValidIdRange; + +/** + * Dedicated logger for rendering a SQL AST + * + * @author Steve Ebersole + */ +@MessageLogger( projectCode = "HHH" ) +@ValidIdRange( min = 90005401, max = 90005500 ) +public interface SqlAstTreeLogger extends BasicLogger { + String LOGGER_NAME = "org.hibernate.orm.sql.ast.tree"; + + /** + * Static access to the logging instance + */ + SqlAstTreeLogger INSTANCE = Logger.getMessageLogger( SqlAstTreeLogger.class, LOGGER_NAME ); + + boolean DEBUG_ENABLED = INSTANCE.isDebugEnabled(); + boolean TRACE_ENABLED = INSTANCE.isTraceEnabled(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/Statement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/Statement.java new file mode 100644 index 0000000000..3be6ccc08c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/Statement.java @@ -0,0 +1,15 @@ +/* + * 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.tree; + +/** + * Base contract for any statement + * + * @author Steve Ebersole + */ +public interface Statement { +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/BinaryArithmeticExpression.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/BinaryArithmeticExpression.java new file mode 100644 index 0000000000..6f58c270d8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/BinaryArithmeticExpression.java @@ -0,0 +1,117 @@ +/* + * 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.tree.expression; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.query.BinaryArithmeticOperator; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.results.internal.ScalarDomainResultImpl; +import org.hibernate.sql.results.internal.SqlSelectionImpl; +import org.hibernate.sql.results.spi.DomainResult; +import org.hibernate.sql.results.spi.DomainResultCreationState; +import org.hibernate.sql.results.spi.DomainResultProducer; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * @author Steve Ebersole + */ +public class BinaryArithmeticExpression + implements Expression, SqlExpressable, DomainResultProducer { + + private final Expression lhsOperand; + private final BinaryArithmeticOperator operator; + private final Expression rhsOperand; + + private final SqlExpressableType resultType; + + public BinaryArithmeticExpression( + Expression lhsOperand, + BinaryArithmeticOperator operator, + Expression rhsOperand, + SqlExpressableType resultType) { + this.operator = operator; + this.lhsOperand = lhsOperand; + this.rhsOperand = rhsOperand; + this.resultType = resultType; + } + + @Override + public SqlExpressableType getExpressableType() { + return resultType; + } + + @Override + public SqlExpressableType getType() { + return getExpressableType(); + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + return new SqlSelectionImpl( + jdbcPosition, + valuesArrayPosition, + this, + getExpressableType() + ); + } + + @Override + public void accept(SqlAstWalker walker) { + walker.visitBinaryArithmeticExpression( this ); + } + + @Override + public DomainResult createDomainResult( + String resultVariable, + DomainResultCreationState creationState) { + final SqlSelection sqlSelection = creationState.getSqlExpressionResolver().resolveSqlSelection( + this, + getType().getJavaTypeDescriptor(), + creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration() + ); + //noinspection unchecked + return new ScalarDomainResultImpl( + sqlSelection.getValuesArrayPosition(), + resultVariable, + resultType.getJavaTypeDescriptor() + ); + } + + /** + * Get the left-hand operand. + * + * @return The left-hand operand. + */ + public Expression getLeftHandOperand() { + return lhsOperand; + } + + /** + * Get the operation + * + * @return The operation + */ + public BinaryArithmeticOperator getOperator() { + return operator; + } + + /** + * Get the right-hand operand. + * + * @return The right-hand operand. + */ + public Expression getRightHandOperand() { + return rhsOperand; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java new file mode 100644 index 0000000000..3d0af9f166 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/ColumnReference.java @@ -0,0 +1,120 @@ +/* + * 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.tree.expression; + +import java.util.Locale; +import java.util.Objects; + +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.exec.spi.JdbcValueExtractor; +import org.hibernate.sql.results.internal.SqlSelectionImpl; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * Models a reference to a Column in a SQL AST + * + * @author Steve Ebersole + */ +public class ColumnReference implements Expression { + private final Identifier columnName; + private final SqlExpressableType sqlExpressableType; + + private String sqlFragment; + + public ColumnReference(ColumnReferenceQualifier qualifier, Identifier columnName, SqlExpressableType sqlExpressableType) { + // the assumption with this assertion is that callers are expecting there + // to be a qualifier; otherwise, they would call the overload ctor form + // not accepting a qualifier + assert qualifier != null : "ColumnReferenceQualifier is null"; + + this.columnName = columnName; + this.sqlExpressableType = sqlExpressableType; + this.sqlFragment = renderSqlFragment( qualifier, columnName ); + } + + private static String renderSqlFragment(ColumnReferenceQualifier qualifier, Identifier columnName) { + if ( qualifier == null ) { + return columnName.render(); + } + else { + final TableReference tableReference = qualifier.locateTableReference( column.getSourceTable() ); + return columnName.render( tableReference.getIdentificationVariable() ); + } + } + + public ColumnReference(Identifier columnName, SqlExpressableType sqlExpressableType) { + this.columnName = columnName; + this.sqlExpressableType = sqlExpressableType; + this.sqlFragment = renderSqlFragment( null, columnName ); + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + final JdbcValueExtractor jdbcValueExtractor = sqlExpressableType.getJdbcValueExtractor(); + return new SqlSelectionImpl( + jdbcPosition, + valuesArrayPosition, + this, + jdbcValueExtractor + ); + } + + public Identifier getColumnName() { + return columnName; + } + + @Override + public void accept(SqlAstWalker interpreter) { + interpreter.visitColumnReference( this ); + } + + @Override + public SqlExpressableType getType() { + return sqlExpressableType; + } + + public String renderSqlFragment() { + return this.sqlFragment; + } + + @Override + public String toString() { + return String.format( + Locale.ROOT, + "%s(%s.%s)", + getClass().getSimpleName(), + sqlFragment, + columnName.getCanonicalName() + ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + ColumnReference that = (ColumnReference) o; + return Objects.equals( sqlFragment, that.sqlFragment ); + } + + @Override + public int hashCode() { + return Objects.hash( sqlFragment ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/EntityTypeLiteral.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/EntityTypeLiteral.java new file mode 100644 index 0000000000..9d868a2971 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/EntityTypeLiteral.java @@ -0,0 +1,52 @@ +/* + * 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.tree.expression; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Queryable; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.type.Type; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * @author Steve Ebersole + */ +public class EntityTypeLiteral implements Expression { + private final EntityPersister entityTypeDescriptor; + private final Type discriminatorType; + + public EntityTypeLiteral(EntityPersister entityTypeDescriptor) { + this.entityTypeDescriptor = entityTypeDescriptor; + this.discriminatorType = ( (Queryable) entityTypeDescriptor ).getDiscriminatorType(); + } + + public EntityPersister getEntityTypeDescriptor() { + return entityTypeDescriptor; + } + + @Override + public SqlExpressableType getType() { + return (SqlExpressableType) discriminatorType; + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + throw new UnsupportedOperationException( "Entity-type literal not supported in select-clause" ); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitEntityTypeLiteral( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/Expression.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/Expression.java new file mode 100644 index 0000000000..aceee8cc27 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/Expression.java @@ -0,0 +1,24 @@ +/* + * 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.tree.expression; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.sql.ast.spi.SqlSelectionProducer; +import org.hibernate.sql.ast.tree.SqlAstNode; + +/** + * Models an expression at the SQL-level. + * + * @author Steve Ebersole + */ +public interface Expression extends SqlAstNode, SqlSelectionProducer { + // + /** + * Access the type for this expression. + */ + SqlExpressableType getType(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SelfRenderingExpression.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SelfRenderingExpression.java new file mode 100644 index 0000000000..4f5e92b026 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SelfRenderingExpression.java @@ -0,0 +1,23 @@ +/* + * 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.tree.expression; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.sql.ast.spi.SqlAppender; +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * @author Steve Ebersole + */ +public interface SelfRenderingExpression extends Expression { + @Override + default void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitSelfRenderingExpression( this ); + } + + void renderToSql(SqlAppender sqlAppender, SqlAstWalker walker, SessionFactoryImplementor sessionFactory); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlExpressable.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlExpressable.java new file mode 100644 index 0000000000..719b6fa94d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlExpressable.java @@ -0,0 +1,23 @@ +/* + * 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.tree.expression; + +import org.hibernate.persister.SqlExpressableType; + +/** + * Unifying contract for things that are capable of being an expression in + * the SQL AST. + * + * @author Steve Ebersole + */ +public interface SqlExpressable { + /** + * Any thing that is expressable at the SQL AST level + * would be of basic type. + */ + SqlExpressableType getExpressableType(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlSelectionExpression.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlSelectionExpression.java new file mode 100644 index 0000000000..ebef7612ef --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlSelectionExpression.java @@ -0,0 +1,60 @@ +/* + * 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.tree.expression; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * Represents a selection that is "re-used" in certain parts of the query + * other than the select-clause (mainly important for order-by, group-by and + * having). Allows usage of the selection position within the select-clause + * in that other part of the query rather than the full expression + * + * @author Steve Ebersole + */ +public class SqlSelectionExpression implements Expression { + private final SqlSelection theSelection; + private final Expression theExpression; + + public SqlSelectionExpression( + SqlSelection theSelection, + Expression theExpression) { + this.theSelection = theSelection; + this.theExpression = theExpression; + } + + public SqlSelection getSelection() { + return theSelection; + } + + public Expression getExpression() { + return theExpression; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitSqlSelectionExpression( this ); + } + + @Override + public SqlExpressableType getType() { + return theExpression.getType(); + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + return theSelection; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlTuple.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlTuple.java new file mode 100644 index 0000000000..d424fabc14 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/expression/SqlTuple.java @@ -0,0 +1,50 @@ +/* + * 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.tree.expression; + +import java.util.List; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.sql.ast.SqlTreeCreationException; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; +import org.hibernate.type.spi.TypeConfiguration; + +/** + * @author Steve Ebersole + */ +public class SqlTuple implements Expression { + private final List expressions; + + public SqlTuple(List expressions) { + this.expressions = expressions; + } + + @Override + public SqlExpressableType getType() { + return null; + } + + @Override + public SqlSelection createSqlSelection( + int jdbcPosition, + int valuesArrayPosition, + JavaTypeDescriptor javaTypeDescriptor, + TypeConfiguration typeConfiguration) { + throw new SqlTreeCreationException( "SqlTuple cannot be used to create a SqlSelection" ); + } + + public List getExpressions(){ + return expressions; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitTuple( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java new file mode 100644 index 0000000000..c7488a45e3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/FromClause.java @@ -0,0 +1,24 @@ +/* + * 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.tree.from; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; + +/** + * + * @author Steve Ebersole + */ +public class FromClause implements SqlAstNode { + public FromClause() { + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitFromClause( this ); + } +} \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroup.java new file mode 100644 index 0000000000..45a7c66489 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroup.java @@ -0,0 +1,79 @@ +/* + * 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.tree.from; + +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; + +import org.hibernate.LockMode; +import org.hibernate.metamodel.model.mapping.spi.ModelPart; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.spi.SqlAppender; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.results.spi.DomainResult; +import org.hibernate.sql.results.spi.DomainResultCreationState; +import org.hibernate.sql.results.spi.DomainResultProducer; + +/** + * Group together {@link TableReference} references related to a single entity or + * collection, along with joins to other TableGroups + * + * @author Steve Ebersole + */ +public interface TableGroup extends SqlAstNode, DomainResultProducer, NavigableReference, ColumnReferenceQualifier { + LockMode getLockMode(); + + ModelPart getModelPart(); + + NavigablePath getNavigablePath(); + + Set getTableGroupJoins(); + + boolean hasTableGroupJoins(); + + void setTableGroupJoins(Set joins); + + void addTableGroupJoin(TableGroupJoin join); + + void visitTableGroupJoins(Consumer consumer); + + void render(SqlAppender sqlAppender, SqlAstWalker walker); + + void applyAffectedTableNames(Consumer nameCollector); + + TableReference getPrimaryTableReference(); + List getTableReferenceJoins(); + + @Override + default DomainResult createDomainResult( + int valuesArrayPosition, + String resultVariable, + DomainResultCreationState creationState) { + return getModelPart().createDomainResult( + getNavigablePath(), + valuesArrayPosition, + resultVariable, + creationState + ); + } + + default ColumnReference locateColumnReferenceByName(String name) { + throw new UnsupportedOperationException( + "Cannot call #locateColumnReferenceByName on this type of TableGroup" + ); + } + + @Override + default void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitTableGroup( this ); + } + + boolean isInnerJoinPossible(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoin.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoin.java new file mode 100644 index 0000000000..7559602e2e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoin.java @@ -0,0 +1,72 @@ +/* + * 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.tree.from; + +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.JoinType; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.predicate.Predicate; +import org.hibernate.sql.results.spi.DomainResult; +import org.hibernate.sql.results.spi.DomainResultCreationState; +import org.hibernate.sql.results.spi.DomainResultProducer; + +/** + * @author Steve Ebersole + */ +public class TableGroupJoin implements SqlAstNode, DomainResultProducer, SqmExpressionInterpretation { + private final NavigablePath navigablePath; + private final JoinType joinType; + private final TableGroup joinedGroup; + private final Predicate predicate; + + public TableGroupJoin( + NavigablePath navigablePath, + JoinType joinType, + TableGroup joinedGroup, + Predicate predicate) { + this.navigablePath = navigablePath; + this.joinType = joinType; + this.joinedGroup = joinedGroup; + this.predicate = predicate; + } + + public JoinType getJoinType() { + return joinType; + } + + public TableGroup getJoinedGroup() { + return joinedGroup; + } + + public Predicate getPredicate() { + return predicate; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitTableGroupJoin( this ); + } + + @Override + public NavigablePath getNavigablePath() { + return navigablePath; + } + + @Override + public Navigable getNavigable() { + return joinedGroup.getNavigable(); + } + + @Override + public DomainResult createDomainResult( + int valuesArrayPosition, + String resultVariable, + DomainResultCreationState creationState) { + return getJoinedGroup().createDomainResult( valuesArrayPosition, resultVariable, creationState ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java new file mode 100644 index 0000000000..22373172de --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupJoinProducer.java @@ -0,0 +1,29 @@ +/* + * 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.tree.from; + +import org.hibernate.LockMode; +import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.JoinType; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableGroupJoin; + +/** + * @author Steve Ebersole + */ +public interface TableGroupJoinProducer extends TableGroupProducer { + /** + * Create a TableGroupJoin as defined for this producer + */ + TableGroupJoin createTableGroupJoin( + NavigablePath navigablePath, + TableGroup lhs, + String explicitSourceAlias, + JoinType joinType, + LockMode lockMode, + SqlAstCreationState creationState); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java new file mode 100644 index 0000000000..1523efbc2e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableGroupProducer.java @@ -0,0 +1,26 @@ +/* + * 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.tree.from; + +/** + * Marker interface for anything which produces a TableGroup + * + * @author Steve Ebersole + * @author Andrea Boriero + */ +public interface TableGroupProducer { + /** + * Get the "stem" used as the base for generating SQL table aliases for table + * references that are part of the TableGroup being generated + *

+ * Note that this is a metadata-ive value. It is only ever used internal to + * the producer producing its TableGroup. + * + * @see org.hibernate.sql.ast.produce.spi.SqlAliasBaseManager#createSqlAliasBase + */ + String getSqlAliasStem(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java new file mode 100644 index 0000000000..0482ee467e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/TableReferenceContributor.java @@ -0,0 +1,24 @@ +/* + * 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.tree.from; + +import org.hibernate.metamodel.model.mapping.spi.TableReferenceJoinCollector; +import org.hibernate.sql.ast.JoinType; + +/** + * @author Steve Ebersole + */ +public interface TableReferenceContributor { + /** + * Apply the Tables mapped by this producer to the collector as TableReferences + */ + void applyTableReferenceJoins( + ColumnReferenceQualifier lhs, + JoinType joinType, + SqlAliasBase sqlAliasBase, + TableReferenceJoinCollector joinCollector); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/package-info.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/package-info.java new file mode 100644 index 0000000000..9f2f8ff654 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/package-info.java @@ -0,0 +1,14 @@ +/* + * 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 defining the SQL AST. + * + * {@link org.hibernate.sql.ast.spi} defines support for creating and + * consuming these trees. + */ +package org.hibernate.sql.ast.tree; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/BetweenPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/BetweenPredicate.java new file mode 100644 index 0000000000..e2b66d666e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/BetweenPredicate.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.sql.ast.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class BetweenPredicate implements Predicate { + private final Expression expression; + private final Expression lowerBound; + private final Expression upperBound; + private final boolean negated; + + public BetweenPredicate( + Expression expression, + Expression lowerBound, + Expression upperBound, + boolean negated) { + this.expression = expression; + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.negated = negated; + } + + public Expression getExpression() { + return expression; + } + + public Expression getLowerBound() { + return lowerBound; + } + + public Expression getUpperBound() { + return upperBound; + } + + public boolean isNegated() { + return negated; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitBetweenPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/ComparisonPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/ComparisonPredicate.java new file mode 100644 index 0000000000..df7d78ed41 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/ComparisonPredicate.java @@ -0,0 +1,51 @@ +/* + * 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.tree.predicate; + +import org.hibernate.query.ComparisonOperator; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class ComparisonPredicate implements Predicate { + private final Expression leftHandExpression; + private ComparisonOperator operator; + private final Expression rightHandExpression; + + public ComparisonPredicate( + Expression leftHandExpression, + ComparisonOperator operator, + Expression rightHandExpression) { + this.leftHandExpression = leftHandExpression; + this.operator = operator; + this.rightHandExpression = rightHandExpression; + } + + public Expression getLeftHandExpression() { + return leftHandExpression; + } + + public Expression getRightHandExpression() { + return rightHandExpression; + } + + public ComparisonOperator getOperator() { + return operator; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitRelationalPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java new file mode 100644 index 0000000000..ef823048a5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java @@ -0,0 +1,30 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * Represents a filter applied to an entity/collection. + *

+ * Note, we do not attempt to parse the filter + * + * @author Steve Ebersole + */ +public class FilterPredicate implements Predicate { + // todo : need to "carry forward" the FilterConfiguration information into the ImprovedEntityPersister so we have access to the alias injections + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitFilterPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/GroupedPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/GroupedPredicate.java new file mode 100644 index 0000000000..d742d30205 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/GroupedPredicate.java @@ -0,0 +1,34 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * @author Steve Ebersole + */ +public class GroupedPredicate implements Predicate { + private final Predicate subPredicate; + + public GroupedPredicate(Predicate subPredicate) { + this.subPredicate = subPredicate; + } + + public Predicate getSubPredicate() { + return subPredicate; + } + + @Override + public boolean isEmpty() { + return subPredicate.isEmpty(); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitGroupedPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InListPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InListPredicate.java new file mode 100644 index 0000000000..e92b21b259 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InListPredicate.java @@ -0,0 +1,76 @@ +/* + * 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.tree.predicate; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class InListPredicate implements Predicate { + private final Expression testExpression; + private final List listExpressions; + private final boolean negated; + + public InListPredicate(Expression testExpression) { + this( testExpression, new ArrayList<>() ); + } + + public InListPredicate(Expression testExpression, boolean negated) { + this( testExpression, new ArrayList<>(), negated ); + } + + public InListPredicate(Expression testExpression, Expression... listExpressions) { + this( testExpression, ArrayHelper.toExpandableList( listExpressions ) ); + } + + public InListPredicate( + Expression testExpression, + List listExpressions) { + this( testExpression, listExpressions, false ); + } + + public InListPredicate( + Expression testExpression, + List listExpressions, + boolean negated) { + this.testExpression = testExpression; + this.listExpressions = listExpressions; + this.negated = negated; + } + + public Expression getTestExpression() { + return testExpression; + } + + public List getListExpressions() { + return listExpressions; + } + + public void addExpression(Expression expression) { + listExpressions.add( expression ); + } + + public boolean isNegated() { + return negated; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitInListPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InSubQueryPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InSubQueryPredicate.java new file mode 100644 index 0000000000..a8500c543b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/InSubQueryPredicate.java @@ -0,0 +1,48 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.select.QuerySpec; + +/** + * @author Steve Ebersole + */ +public class InSubQueryPredicate implements Predicate { + private final Expression testExpression; + private final QuerySpec subQuery; + private final boolean negated; + + public InSubQueryPredicate(Expression testExpression, QuerySpec subQuery, boolean negated) { + this.testExpression = testExpression; + this.subQuery = subQuery; + this.negated = negated; + } + + public Expression getTestExpression() { + return testExpression; + } + + public QuerySpec getSubQuery() { + return subQuery; + } + + public boolean isNegated() { + return negated; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitInSubQueryPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java new file mode 100644 index 0000000000..f37305d96a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java @@ -0,0 +1,57 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.sql.ast.tree.predicate; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * @author Steve Ebersole + */ +public class Junction implements Predicate { + public enum Nature { + /** + * An AND + */ + CONJUNCTION, + /** + * An OR + */ + DISJUNCTION + } + + private final Nature nature; + private final List predicates = new ArrayList<>(); + + public Junction(Nature nature) { + this.nature = nature; + } + + public void add(Predicate predicate) { + predicates.add( predicate ); + } + + public Nature getNature() { + return nature; + } + + public List getPredicates() { + return predicates; + } + + @Override + public boolean isEmpty() { + return predicates.isEmpty(); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitJunction( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/LikePredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/LikePredicate.java new file mode 100644 index 0000000000..cfb6d65840 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/LikePredicate.java @@ -0,0 +1,67 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class LikePredicate implements Predicate { + private final Expression matchExpression; + private final Expression pattern; + private final Expression escapeCharacter; + private final boolean negated; + + public LikePredicate( + Expression matchExpression, + Expression pattern, + Expression escapeCharacter) { + this( matchExpression, pattern, escapeCharacter, false ); + } + + public LikePredicate( + Expression matchExpression, + Expression pattern, + Expression escapeCharacter, boolean negated) { + this.matchExpression = matchExpression; + this.pattern = pattern; + this.escapeCharacter = escapeCharacter; + this.negated = negated; + } + + public LikePredicate(Expression matchExpression, Expression pattern) { + this( matchExpression, pattern, null ); + } + + public Expression getMatchExpression() { + return matchExpression; + } + + public Expression getPattern() { + return pattern; + } + + public Expression getEscapeCharacter() { + return escapeCharacter; + } + + public boolean isNegated() { + return negated; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitLikePredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NegatedPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NegatedPredicate.java new file mode 100644 index 0000000000..504b855a32 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NegatedPredicate.java @@ -0,0 +1,34 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; + +/** + * @author Steve Ebersole + */ +public class NegatedPredicate implements Predicate { + private final Predicate predicate; + + public NegatedPredicate(Predicate predicate) { + this.predicate = predicate; + } + + public Predicate getPredicate() { + return predicate; + } + + @Override + public boolean isEmpty() { + return predicate.isEmpty(); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitNegatedPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NullnessPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NullnessPredicate.java new file mode 100644 index 0000000000..ba50ff6059 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/NullnessPredicate.java @@ -0,0 +1,41 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class NullnessPredicate implements Predicate { + private final Expression expression; + private final boolean negated; + + public NullnessPredicate(Expression expression, boolean negated) { + this.expression = expression; + this.negated = negated; + } + + public Expression getExpression() { + return expression; + } + + public boolean isNegated() { + return negated; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitNullnessPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Predicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Predicate.java new file mode 100644 index 0000000000..dd2f57f7b6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Predicate.java @@ -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.tree.predicate; + +import org.hibernate.sql.ast.tree.SqlAstNode; + +/** + * @author Steve Ebersole + */ +public interface Predicate extends SqlAstNode { + boolean isEmpty(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/PredicateContainer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/PredicateContainer.java new file mode 100644 index 0000000000..cdeaf5ed85 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/PredicateContainer.java @@ -0,0 +1,19 @@ +/* + * 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.tree.predicate; + +/** + * Something that can contain predicates + * + * @author Steve Ebersole + */ +public interface PredicateContainer { + /** + * Apply a predicate to this container + */ + void applyPredicate(Predicate predicate); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/SelfRenderingPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/SelfRenderingPredicate.java new file mode 100644 index 0000000000..c512d928bd --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/SelfRenderingPredicate.java @@ -0,0 +1,36 @@ +/* + * 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.tree.predicate; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression; + +/** + * + * @author Chris Cranford + */ +public class SelfRenderingPredicate implements Predicate { + private final SelfRenderingExpression selfRenderingExpression; + + public SelfRenderingPredicate(SelfRenderingExpression expression) { + this.selfRenderingExpression = expression; + } + + public SelfRenderingExpression getSelfRenderingExpression() { + return selfRenderingExpression; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitSelfRenderingPredicate( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java new file mode 100644 index 0000000000..757e614ebc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/QuerySpec.java @@ -0,0 +1,101 @@ +/* + * 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.tree.select; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import org.hibernate.sql.ast.spi.SqlAstTreeHelper; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.ast.tree.from.FromClause; +import org.hibernate.sql.ast.tree.predicate.Predicate; +import org.hibernate.sql.ast.tree.predicate.PredicateContainer; + +/** + * @author Steve Ebersole + */ +public class QuerySpec implements SqlAstNode, PredicateContainer { + private final boolean isRoot; + + private final FromClause fromClause = new FromClause(); + private final SelectClause selectClause = new SelectClause(); + + private Predicate whereClauseRestrictions; + private List sortSpecifications; + private Expression limitClauseExpression; + private Expression offsetClauseExpression; + + public QuerySpec(boolean isRoot) { + this.isRoot = isRoot; + } + + /** + * Does this QuerySpec map to the statement's root query (as + * opposed to one of its sub-queries)? + */ + public boolean isRoot() { + return isRoot; + } + + public FromClause getFromClause() { + return fromClause; + } + + public SelectClause getSelectClause() { + return selectClause; + } + + public Predicate getWhereClauseRestrictions() { + return whereClauseRestrictions; + } + + @Override + public void applyPredicate(Predicate predicate) { + this.whereClauseRestrictions = SqlAstTreeHelper.combinePredicates( this.whereClauseRestrictions, predicate ); + } + + public List getSortSpecifications() { + return sortSpecifications; + } + + void visitSortSpecifications(Consumer consumer) { + if ( sortSpecifications != null ) { + sortSpecifications.forEach( consumer ); + } + } + + public void addSortSpecification(SortSpecification specification) { + if ( sortSpecifications == null ) { + sortSpecifications = new ArrayList<>(); + } + sortSpecifications.add( specification ); + } + + public Expression getLimitClauseExpression() { + return limitClauseExpression; + } + + public void setLimitClauseExpression(Expression limitClauseExpression) { + this.limitClauseExpression = limitClauseExpression; + } + + public Expression getOffsetClauseExpression() { + return offsetClauseExpression; + } + + public void setOffsetClauseExpression(Expression offsetClauseExpression) { + this.offsetClauseExpression = offsetClauseExpression; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitQuerySpec( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectClause.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectClause.java new file mode 100644 index 0000000000..da5e12ae09 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectClause.java @@ -0,0 +1,52 @@ +/* + * 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.tree.select; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.hibernate.internal.util.collections.UniqueList; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.SqlAstNode; + +/** + * @author Steve Ebersole + */ +public class SelectClause implements SqlAstNode { + private boolean distinct; + private final UniqueList sqlSelections = new UniqueList<>(); + + public SelectClause() { + } + + public void makeDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getSqlSelectionList() { + return Collections.unmodifiableList( sqlSelections ); + } + + public Set getSqlSelections() { + return Collections.unmodifiableSet( sqlSelections ); + } + + public void addSqlSelection(SqlSelection sqlSelection) { + sqlSelections.add( sqlSelection ); + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitSelectClause( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectStatement.java new file mode 100644 index 0000000000..5cb1d34766 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectStatement.java @@ -0,0 +1,24 @@ +/* + * 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.tree.select; + +import org.hibernate.sql.ast.tree.Statement; + +/** + * @author Steve Ebersole + */ +public class SelectStatement implements Statement { + private final QuerySpec querySpec; + + public SelectStatement(QuerySpec querySpec) { + this.querySpec = querySpec; + } + + public QuerySpec getQuerySpec() { + return querySpec; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SortSpecification.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SortSpecification.java new file mode 100644 index 0000000000..abeb2dd59b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SortSpecification.java @@ -0,0 +1,44 @@ +/* + * 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.tree.select; + +import org.hibernate.SortOrder; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class SortSpecification implements SqlAstNode { + private final Expression sortExpression; + private final String collation; + private final SortOrder sortOrder; + + public SortSpecification(Expression sortExpression, String collation, SortOrder sortOrder) { + this.sortExpression = sortExpression; + this.collation = collation; + this.sortOrder = sortOrder; + } + + public Expression getSortExpression() { + return sortExpression; + } + + public String getCollation() { + return collation; + } + + public SortOrder getSortOrder() { + return sortOrder; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitSortSpecification( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/Assignment.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/Assignment.java new file mode 100644 index 0000000000..6846e061d7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/Assignment.java @@ -0,0 +1,41 @@ +/* + * 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.tree.update; + +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.tree.SqlAstNode; +import org.hibernate.sql.ast.tree.expression.ColumnReference; +import org.hibernate.sql.ast.tree.expression.Expression; + +/** + * @author Steve Ebersole + */ +public class Assignment implements SqlAstNode { + private final ColumnReference columnReference; + private final Expression assignedValue; + + public Assignment(ColumnReference columnReference, Expression assignedValue) { + this.columnReference = columnReference; + this.assignedValue = assignedValue; + } + + /** + * The column being updated. + */ + public ColumnReference getColumnReference() { + return columnReference; + } + + public Expression getAssignedValue() { + return assignedValue; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitAssignment( this ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java new file mode 100644 index 0000000000..028ff69138 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/update/UpdateStatement.java @@ -0,0 +1,91 @@ +/* + * 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.tree.update; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.hibernate.sql.ast.spi.SqlAstTreeHelper; +import org.hibernate.sql.ast.tree.MutationStatement; +import org.hibernate.sql.ast.tree.predicate.Predicate; +import org.hibernate.sql.ast.tree.predicate.PredicateContainer; + +/** + * @author Steve Ebersole + */ +public class UpdateStatement implements MutationStatement { + private final TableReference targetTable; + private final List assignments; + private final Predicate restriction; + + public UpdateStatement( + TableReference targetTable, + List assignments, + Predicate restriction) { + this.targetTable = targetTable; + this.assignments = assignments; + this.restriction = restriction; + } + + public TableReference getTargetTable() { + return targetTable; + } + + public List getAssignments() { + return assignments; + } + + public Predicate getRestriction() { + return restriction; + } + + + public static class UpdateStatementBuilder { + private final TableReference targetTableRef; + private List assignments; + private Predicate restriction; + + public UpdateStatementBuilder(TableReference targetTableRef) { + this.targetTableRef = targetTableRef; + } + + public UpdateStatementBuilder addAssignment(Assignment assignment) { + if ( assignments == null ) { + assignments = new ArrayList<>(); + } + assignments.add( assignment ); + + return this; + } + + public UpdateStatementBuilder addRestriction(Predicate restriction) { + this.restriction = SqlAstTreeHelper.combinePredicates( this.restriction, restriction ); + return this; + } + + public UpdateStatementBuilder setRestriction(Predicate restriction) { + this.restriction = restriction; + return this; + } + + public SqlAstUpdateDescriptor createUpdateDescriptor() { + return new SqlAstUpdateDescriptorImpl( + createUpdateAst(), + Collections.singleton( targetTableRef.getTable().getTableExpression() ) + ); + } + + public UpdateStatement createUpdateAst() { + if ( assignments == null || assignments.isEmpty() ) { + return null; + } + + return new UpdateStatement( targetTableRef, assignments, restriction ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/BasicResultAssembler.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/BasicResultAssembler.java index 3d42a05618..152d100380 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/BasicResultAssembler.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/BasicResultAssembler.java @@ -6,10 +6,9 @@ */ package org.hibernate.sql.results.internal; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; -import org.hibernate.metamodel.model.convert.spi.ConvertibleValueMapping; -import org.hibernate.query.sqm.SqmExpressable; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.results.SqlResultsLogger; import org.hibernate.sql.results.spi.DomainResultAssembler; import org.hibernate.sql.results.spi.JdbcValuesSourceProcessingOptions; import org.hibernate.sql.results.spi.RowProcessingState; @@ -19,32 +18,53 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; * @author Steve Ebersole */ public class BasicResultAssembler implements DomainResultAssembler { - private final SqmExpressable expressableType; - private final BasicValueConverter valueConverter; - - public BasicResultAssembler(SqmExpressable expressableType) { - this( - expressableType, - expressableType instanceof ConvertibleValueMapping - ? ( (ConvertibleValueMapping) expressableType ).getValueConverter() - : null - ); + public static BasicResultAssembler from(SqlSelection selection, JavaTypeDescriptor javaTypeDescriptor) { + return new BasicResultAssembler<>( selection.getValuesArrayPosition(), javaTypeDescriptor ); } - public BasicResultAssembler(SqmExpressable expressableType, BasicValueConverter valueConverter) { - this.expressableType = expressableType; + private final int valuesArrayPosition; + private final JavaTypeDescriptor assembledJavaTypeDescriptor; + private final BasicValueConverter valueConverter; + + public BasicResultAssembler( + int valuesArrayPosition, + JavaTypeDescriptor assembledJavaTypeDescriptor) { + this( valuesArrayPosition, assembledJavaTypeDescriptor, null ); + } + + public BasicResultAssembler( + int valuesArrayPosition, + JavaTypeDescriptor assembledJavaTypeDescriptor, + BasicValueConverter valueConverter) { + this.valuesArrayPosition = valuesArrayPosition; + this.assembledJavaTypeDescriptor = assembledJavaTypeDescriptor; this.valueConverter = valueConverter; } @Override - public Object assemble( + public J assemble( RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) { - throw new NotYetImplementedFor6Exception(); + Object jdbcValue = rowProcessingState.getJdbcValue( valuesArrayPosition ); + + SqlResultsLogger.INSTANCE.debugf( "Extracted JDBC value [%d] - [%s]", valuesArrayPosition, jdbcValue ); + + if ( valueConverter != null ) { + // the raw value type should be the converter's relational-JTD + assert ( jdbcValue == null || valueConverter.getRelationalJavaDescriptor().getJavaType().isInstance( jdbcValue ) ) + : "Expecting raw JDBC value of type [" + valueConverter.getRelationalJavaDescriptor().getJavaType().getName() + + "] but found [" + jdbcValue + ']'; + + //noinspection unchecked + return (J) ( (BasicValueConverter) valueConverter ).toDomainValue( jdbcValue ); + } + + //noinspection unchecked + return (J) jdbcValue; } @Override - public JavaTypeDescriptor getJavaTypeDescriptor() { - return expressableType.getExpressableJavaTypeDescriptor(); + public JavaTypeDescriptor getAssembledJavaTypeDescriptor() { + return assembledJavaTypeDescriptor; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerDefined.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerDefined.java index a9a63d4a18..8ccd3c4a48 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerDefined.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerDefined.java @@ -14,7 +14,7 @@ import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.JdbcValuesMapping; import org.hibernate.sql.results.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.spi.JdbcValuesMetadata; -import org.hibernate.sql.results.spi.SqlSelection; +import org.hibernate.sql.ast.spi.SqlSelection; /** * ResultSetMapping for handling selections for a {@link org.hibernate.query.NativeQuery} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerStandard.java index 1a634b92ac..533774e566 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerStandard.java @@ -15,7 +15,7 @@ import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.JdbcValuesMapping; import org.hibernate.sql.results.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.spi.JdbcValuesMetadata; -import org.hibernate.sql.results.spi.SqlSelection; +import org.hibernate.sql.ast.spi.SqlSelection; /** * Hibernate's standard ResultSetMappingDescriptor implementation for cases diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerUndefined.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerUndefined.java index 90b7730aad..65f3c58f4a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerUndefined.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/JdbcValuesMappingProducerUndefined.java @@ -18,7 +18,7 @@ import org.hibernate.sql.results.spi.DomainResult; import org.hibernate.sql.results.spi.JdbcValuesMapping; import org.hibernate.sql.results.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.spi.JdbcValuesMetadata; -import org.hibernate.sql.results.spi.SqlSelection; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; import org.hibernate.type.spi.TypeConfiguration; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ScalarDomainResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ScalarDomainResultImpl.java index 4fe9e84d29..1ed106bb7a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ScalarDomainResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ScalarDomainResultImpl.java @@ -9,8 +9,6 @@ package org.hibernate.sql.results.internal; import java.util.function.Consumer; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; -import org.hibernate.metamodel.model.convert.spi.ConvertibleValueMapping; -import org.hibernate.query.sqm.SqmExpressable; import org.hibernate.sql.results.spi.AssemblerCreationState; import org.hibernate.sql.results.spi.DomainResultAssembler; import org.hibernate.sql.results.spi.Initializer; @@ -22,27 +20,29 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor; */ public class ScalarDomainResultImpl implements ScalarDomainResult { private final String resultVariable; - private final SqmExpressable expressableType; + private final JavaTypeDescriptor javaTypeDescriptor; private final DomainResultAssembler assembler; public ScalarDomainResultImpl( + int valuesArrayPosition, String resultVariable, - SqmExpressable expressableType) { + JavaTypeDescriptor javaTypeDescriptor) { this.resultVariable = resultVariable; - this.expressableType = expressableType; + this.javaTypeDescriptor = javaTypeDescriptor; - this.assembler = new BasicResultAssembler<>( expressableType ); + this.assembler = new BasicResultAssembler<>( valuesArrayPosition, javaTypeDescriptor ); } public ScalarDomainResultImpl( + int valuesArrayPosition, String resultVariable, - SqmExpressable expressableType, + JavaTypeDescriptor javaTypeDescriptor, BasicValueConverter valueConverter) { this.resultVariable = resultVariable; - this.expressableType = expressableType; + this.javaTypeDescriptor = javaTypeDescriptor; - this.assembler = new BasicResultAssembler<>( expressableType, valueConverter ); + this.assembler = new BasicResultAssembler<>( valuesArrayPosition, javaTypeDescriptor, valueConverter ); } @Override @@ -52,7 +52,7 @@ public class ScalarDomainResultImpl implements ScalarDomainResult { @Override public JavaTypeDescriptor getResultJavaTypeDescriptor() { - return expressableType.getExpressableJavaTypeDescriptor(); + return javaTypeDescriptor; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/SqlSelectionImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/SqlSelectionImpl.java new file mode 100644 index 0000000000..ea4e33d3f0 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/SqlSelectionImpl.java @@ -0,0 +1,75 @@ +/* + * 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.results.internal; + +import java.util.Objects; + +import org.hibernate.persister.SqlExpressableType; +import org.hibernate.sql.ast.spi.SqlAstWalker; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.expression.Expression; +import org.hibernate.sql.exec.spi.JdbcValueExtractor; + +/** + * @author Steve Ebersole + */ +public class SqlSelectionImpl implements SqlSelection { + private final int jdbcPosition; + private final int valuesArrayPosition; + private final Expression sqlExpression; + private final JdbcValueExtractor jdbcValueExtractor; + + public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, SqlExpressableType sqlExpressableType) { + this( jdbcPosition, valuesArrayPosition, sqlExpression, sqlExpressableType.getJdbcValueExtractor() ); + } + + public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, JdbcValueExtractor jdbcValueExtractor) { + this.jdbcPosition = jdbcPosition; + this.valuesArrayPosition = valuesArrayPosition; + this.sqlExpression = sqlExpression; + this.jdbcValueExtractor = jdbcValueExtractor; + } + + @Override + public JdbcValueExtractor getJdbcValueExtractor() { + return jdbcValueExtractor; + } + + @Override + public int getJdbcResultSetIndex() { + return jdbcPosition; + } + + @Override + public int getValuesArrayPosition() { + return valuesArrayPosition; + } + + @Override + public void accept(SqlAstWalker interpreter) { + sqlExpression.accept( interpreter ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SqlSelectionImpl that = (SqlSelectionImpl) o; + return jdbcPosition == that.jdbcPosition && + valuesArrayPosition == that.valuesArrayPosition && + Objects.equals( sqlExpression, that.sqlExpression ); + } + + @Override + public int hashCode() { + return Objects.hash( jdbcPosition, valuesArrayPosition, sqlExpression ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultAssembler.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultAssembler.java index c051b9fbf2..2ee043807a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultAssembler.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultAssembler.java @@ -20,12 +20,12 @@ public interface DomainResultAssembler { /** * The main "assembly" contract. Assemble the result and return it. */ - Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options); + J assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options); /** * Convenience form of {@link #assemble(RowProcessingState, JdbcValuesSourceProcessingOptions)} */ - default Object assemble(RowProcessingState rowProcessingState) { + default J assemble(RowProcessingState rowProcessingState) { return assemble( rowProcessingState, rowProcessingState.getJdbcValuesSourceProcessingState().getProcessingOptions() ); } @@ -33,5 +33,5 @@ public interface DomainResultAssembler { * The JavaTypeDescriptor describing the Java type that this assembler * assembles. */ - JavaTypeDescriptor getJavaTypeDescriptor(); + JavaTypeDescriptor getAssembledJavaTypeDescriptor(); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java index 40205de2e2..aa865f94d9 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultCreationState.java @@ -6,8 +6,48 @@ */ package org.hibernate.sql.results.spi; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.sql.ast.spi.SqlAliasBaseManager; +import org.hibernate.sql.ast.spi.SqlAstCreationState; + /** * @author Steve Ebersole */ public interface DomainResultCreationState { + SqlAstCreationState getSqlAstCreationState(); + + default SqlAliasBaseManager getSAliasBaseManager() { + return getSqlAstCreationState().getSqlAliasBaseManager(); + } + + /** + * todo (6.0) : centralize the implementation of this + * most of the logic in the impls of this is identical. variations (arguments) include: + * 1) given a Fetchable, determine the FetchTiming and `selected`[1]. Tricky as functional + * interface because of the "composite return". + * 2) given a Fetchable, determine the LockMode - currently not handled very well here; should consult `#getLockOptions` + * - perhaps a functional interface accepting the FetchParent and Fetchable and returning the LockMode + * + * so something like: + * List visitFetches( + * FetchParent fetchParent, + * BiFunction fetchStrategyResolver, + * BiFunction lockModeResolver) + * + * [1] `selected` refers to the named parameter in + * {@link Fetchable#generateFetch(FetchParent, org.hibernate.engine.FetchTiming, boolean, LockMode, String, DomainResultCreationState)}. + * For {@link org.hibernate.engine.FetchTiming#IMMEDIATE}, this boolean value indicates + * whether the values for the generated assembler/initializers are or should be available in + * the {@link JdbcValues} being processed. For {@link org.hibernate.engine.FetchTiming#DELAYED} this + * parameter has no effect + * + * todo (6.0) : wrt the "trickiness" of `selected[1]`, that may no longer be an issue given how TableGroups + * are built/accessed. Comes down to how we'd know whether to join fetch or select fetch. Simply pass + * along FetchStyle? + * + * + */ + List visitFetches(FetchParent fetchParent); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultProducer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultProducer.java index 34c76f8a4c..963b7f520e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/DomainResultProducer.java @@ -18,6 +18,7 @@ public interface DomainResultProducer { * Produce the domain query */ DomainResult createDomainResult( + int valuesArrayPosition, String resultVariable, DomainResultCreationState creationState); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetch.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetch.java new file mode 100644 index 0000000000..d775061086 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetch.java @@ -0,0 +1,64 @@ +/* + * 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.results.spi; + +import java.util.function.Consumer; + +import org.hibernate.metamodel.model.mapping.spi.ValueMapping; +import org.hibernate.query.NavigablePath; + +/** + * Contract for fetches including entity, collection and composite. Acts as the + * producer for the {@link DomainResultAssembler} for this result as well + * as any {@link Initializer} instances needed + * + * todo (6.0) : we have fetch -> fetch-parent at the initializer level. Do we also need fetch-parent -> fetch(es)? + * - depends how the parent state gets resolved for injection into the parent instance + * + * @see EntityFetch + * @see CollectionFetch + * @see CompositeFetch + * + * @author Steve Ebersole + */ +public interface Fetch { + /** + * Obtain the owner of this fetch. Ultimately used to identify + * the thing that "owns" this fetched navigable for the purpose of: + *

+ * * identifying the associated owner reference as we process the fetch + * * inject the fetched instance into the parent and potentially inject + * the parent reference into the fetched instance if it defines + * such injection (e.g. {@link org.hibernate.annotations.Parent}) + */ + FetchParent getFetchParent(); + + /** + * The value mapping being fetched + */ + ValueMapping getFetchedValueMapping(); + + /** + * Get the property path to this fetch + * + * @return The property path + */ + NavigablePath getNavigablePath(); + + /** + * Is this fetch nullable? Meaning is it mapped as being optional? + */ + boolean isNullable(); + + /** + * Create the assembler for this fetch + */ + DomainResultAssembler createAssembler( + FetchParentAccess parentAccess, + Consumer collector, + AssemblerCreationState creationState); +} \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParent.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParent.java new file mode 100644 index 0000000000..4f77569d8b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParent.java @@ -0,0 +1,31 @@ +/* + * 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.results.spi; + +import java.util.List; + +import org.hibernate.metamodel.model.mapping.spi.ValueMappingContainer; +import org.hibernate.query.NavigablePath; + +/** + * Contract for things that can be the parent of a fetch + * + * @author Steve Ebersole + */ +public interface FetchParent { + ValueMappingContainer getReferencedMappingContainer(); + + /** + * Get the property path to this parent + */ + NavigablePath getNavigablePath(); + + /** + * Retrieve the fetches owned by this fetch source. + */ + List getFetches(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParentAccess.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParentAccess.java new file mode 100644 index 0000000000..e9ddf16c04 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/FetchParentAccess.java @@ -0,0 +1,30 @@ +/* + * 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.results.spi; + +import java.util.function.Consumer; + +import org.hibernate.query.NavigablePath; + +/** + * Serves as a link to a fetch's parent providing access to the parent + * instance in relation to the current "row" being processed. + * + * @author Steve Ebersole + */ +public interface FetchParentAccess { + FetchParentAccess findFirstEntityDescriptorAccess(); + + /** + * Access to the fetch's parent instance. + */ + Object getFetchParentInstance(); + + NavigablePath getNavigablePath(); + + void registerResolutionListener(Consumer resolvedParentConsumer); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetchable.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetchable.java new file mode 100644 index 0000000000..553311becc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/Fetchable.java @@ -0,0 +1,37 @@ +/* + * 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.results.spi; + +import org.hibernate.LockMode; +import org.hibernate.engine.FetchStrategy; +import org.hibernate.engine.FetchTiming; +import org.hibernate.metamodel.model.mapping.spi.ValueMapping; + +/** + * @author Steve Ebersole + */ +public interface Fetchable extends ValueMapping { + FetchStrategy getMappedFetchStrategy(); + + // todo (6.0) : all we need here is (1) FetchTiming and (2) whether the values are available in the current JdbcValuesSource + // Having to instantiate new FetchStrategy potentially multiple times + // per Fetch generation is performance drain. Would be better to + // simply pass these 2 pieces of information + + Fetch generateFetch( + FetchParent fetchParent, + FetchTiming fetchTiming, + boolean selected, + LockMode lockMode, + String resultVariable, + DomainResultCreationState creationState); + + default boolean isCircular(FetchParent fetchParent){ + return false; + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/JdbcValuesMapping.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/JdbcValuesMapping.java index 2148603466..3661714dfd 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/JdbcValuesMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/JdbcValuesMapping.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Set; import java.util.function.Consumer; +import org.hibernate.sql.ast.spi.SqlSelection; + /** * The "resolved" form of {@link JdbcValuesMappingDescriptor} providing access * to resolved JDBC results ({@link SqlSelection}) descriptors and resolved diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/RowProcessingState.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/RowProcessingState.java index 626f34b410..43557c4531 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/RowProcessingState.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/RowProcessingState.java @@ -7,6 +7,7 @@ package org.hibernate.sql.results.spi; import org.hibernate.query.NavigablePath; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.exec.spi.ExecutionContext; /** diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelectionGroupNode.java b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelectionGroupNode.java index 6c894a40cb..2ad4e6884b 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelectionGroupNode.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/spi/SqlSelectionGroupNode.java @@ -8,6 +8,8 @@ package org.hibernate.sql.results.spi; import java.util.function.Consumer; +import org.hibernate.sql.ast.spi.SqlSelection; + /** * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java index 65c5e76382..2354717d86 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/AbstractAttribute.java @@ -34,4 +34,6 @@ public abstract class AbstractAttribute implements Attribute, Property { public Type getType() { return attributeType; } + + } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java b/hibernate-core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java index 0f601bf475..8781e659cb 100755 --- a/hibernate-core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java @@ -13,6 +13,7 @@ import java.util.Map; import java.util.Set; import org.hibernate.mapping.PersistentClass; +import org.hibernate.metamodel.spi.Instantiator; public class DynamicMapInstantiator implements Instantiator { public static final String KEY = "$type$"; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/Instantiator.java b/hibernate-core/src/main/java/org/hibernate/tuple/Instantiator.java deleted file mode 100644 index 567007ee34..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tuple/Instantiator.java +++ /dev/null @@ -1,43 +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 . - */ -package org.hibernate.tuple; -import java.io.Serializable; - -/** - * Contract for implementors responsible for instantiating entity/component instances. - * - * @author Steve Ebersole - */ -public interface Instantiator extends Serializable { - - /** - * Perform the requested entity instantiation. - *

- * This form is never called for component instantiation, only entity instantiation. - * - * @param id The id of the entity to be instantiated. - * @return An appropriately instantiated entity. - */ - public Object instantiate(Serializable id); - - /** - * Perform the requested instantiation. - * - * @return The instantiated data structure. - */ - public Object instantiate(); - - /** - * Performs check to see if the given object is an instance of the entity - * or component which this Instantiator instantiates. - * - * @param object The object to be checked. - * @return True is the object does represent an instance of the underlying - * entity/component. - */ - public boolean isInstance(Object object); -} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/PojoInstantiator.java b/hibernate-core/src/main/java/org/hibernate/tuple/PojoInstantiator.java index d4343fa958..6a8a3c3093 100755 --- a/hibernate-core/src/main/java/org/hibernate/tuple/PojoInstantiator.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/PojoInstantiator.java @@ -13,10 +13,12 @@ import java.lang.reflect.Constructor; import org.hibernate.InstantiationException; import org.hibernate.PropertyNotFoundException; import org.hibernate.bytecode.spi.ReflectionOptimizer; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.mapping.Component; +import org.hibernate.metamodel.spi.Instantiator; /** * Defines a POJO-based instantiator for use from the tuplizers. @@ -98,6 +100,11 @@ public class PojoInstantiator implements Instantiator, Serializable { return entity; } + @Override + public Object instantiate(SharedSessionContractImplementor session) { + return null; + } + public Object instantiate(Serializable id) { final boolean useEmbeddedIdentifierInstanceAsEntity = embeddedIdentifier && id != null && diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java index d18b8bfe89..a426da1f2f 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java @@ -14,7 +14,7 @@ import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; /** * Support for tuplizers relating to components. diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java index 295fdd88fe..49414211d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java @@ -1,46 +1,46 @@ -/* - * 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 . - */ -package org.hibernate.tuple.component; -import java.util.Map; - -import org.hibernate.mapping.Component; -import org.hibernate.mapping.Property; -import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl; -import org.hibernate.property.access.spi.Getter; -import org.hibernate.property.access.spi.Setter; -import org.hibernate.tuple.DynamicMapInstantiator; -import org.hibernate.tuple.Instantiator; - -/** - * A {@link ComponentTuplizer} specific to the dynamic-map entity mode. - * - * @author Gavin King - * @author Steve Ebersole - */ -public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer { - - public Class getMappedClass() { - return Map.class; - } - - protected Instantiator buildInstantiator(Component component) { - return new DynamicMapInstantiator(); - } - - public DynamicMapComponentTuplizer(Component component) { - super(component); - } - - protected Getter buildGetter(Component component, Property prop) { - return PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess( null, prop.getName() ).getGetter(); - } - - protected Setter buildSetter(Component component, Property prop) { - return PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess( null, prop.getName() ).getSetter(); - } - -} +/* + * 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 . + */ +package org.hibernate.tuple.component; +import java.util.Map; + +import org.hibernate.mapping.Component; +import org.hibernate.mapping.Property; +import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl; +import org.hibernate.property.access.spi.Getter; +import org.hibernate.property.access.spi.Setter; +import org.hibernate.tuple.DynamicMapInstantiator; +import org.hibernate.metamodel.spi.Instantiator; + +/** + * A {@link ComponentTuplizer} specific to the dynamic-map entity mode. + * + * @author Gavin King + * @author Steve Ebersole + */ +public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer { + + public Class getMappedClass() { + return Map.class; + } + + protected Instantiator buildInstantiator(Component component) { + return new DynamicMapInstantiator(); + } + + public DynamicMapComponentTuplizer(Component component) { + super(component); + } + + protected Getter buildGetter(Component component, Property prop) { + return PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess( null, prop.getName() ).getGetter(); + } + + protected Setter buildSetter(Component component, Property prop) { + return PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess( null, prop.getName() ).getSetter(); + } + +} diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java index 6c21250af3..5c0c053e73 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java @@ -22,7 +22,7 @@ import org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.property.access.spi.Setter; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.PojoInstantiator; /** diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java index 3d137219d0..264ee53b67 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java @@ -34,8 +34,8 @@ import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.ProxyFactory; -import org.hibernate.tuple.IdentifierProperty; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; +import org.hibernate.tuple.NonIdentifierAttribute; import org.hibernate.type.AssociationType; import org.hibernate.type.ComponentType; import org.hibernate.type.CompositeType; @@ -682,7 +682,7 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer { @Override public final Object instantiate(Serializable id, SharedSessionContractImplementor session) { - Object result = getInstantiator().instantiate( id ); + Object result = getInstantiator().instantiate( session ); if ( id != null ) { setIdentifier( result, id, session ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java index e119bd0be9..705231e42d 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java @@ -23,7 +23,7 @@ import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.map.MapProxyFactory; import org.hibernate.tuple.DynamicMapInstantiator; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; /** * An {@link EntityTuplizer} specific to the dynamic-map entity mode. diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java index 57c61115c8..140aaf4b26 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java @@ -35,7 +35,7 @@ import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.ProxyFactory; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.type.CompositeType; /** diff --git a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java index e6263460b8..12558d2e7b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/EnumType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/EnumType.java @@ -19,6 +19,7 @@ import javax.persistence.MapKeyEnumerated; import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; +import org.hibernate.annotations.Nationalized; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreLogging; @@ -27,7 +28,10 @@ import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter; import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter; import org.hibernate.metamodel.model.convert.spi.EnumValueConverter; +import org.hibernate.type.descriptor.java.BasicJavaDescriptor; import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfigurationAware; import org.hibernate.usertype.DynamicParameterizedType; @@ -104,11 +108,29 @@ public class EnumType .getJavaTypeDescriptorRegistry() .getDescriptor( enumClass ); + final BasicJavaDescriptor relationalJavaDescriptor = resolveRelationalJavaTypeDescriptor( + reader, + enumType, + enumJavaDescriptor + ); + + final SqlTypeDescriptor sqlTypeDescriptor = relationalJavaDescriptor.getJdbcRecommendedSqlType( + new LocalSqlTypeDescriptorIndicators( enumType, reader ) + ); + if ( isOrdinal ) { - this.enumValueConverter = new OrdinalEnumValueConverter( enumJavaDescriptor ); + this.enumValueConverter = new OrdinalEnumValueConverter( + enumJavaDescriptor, + sqlTypeDescriptor, + relationalJavaDescriptor + ); } else { - this.enumValueConverter = new NamedEnumValueConverter( enumJavaDescriptor ); + this.enumValueConverter = new NamedEnumValueConverter( + enumJavaDescriptor, + sqlTypeDescriptor, + relationalJavaDescriptor + ); } } else { @@ -130,6 +152,13 @@ public class EnumType ); } + private BasicJavaDescriptor resolveRelationalJavaTypeDescriptor( + ParameterType reader, + javax.persistence.EnumType enumType, EnumJavaTypeDescriptor enumJavaDescriptor) { + return enumJavaDescriptor.getJdbcRecommendedSqlType( new LocalSqlTypeDescriptorIndicators( enumType, reader ) ) + .getJdbcRecommendedJavaTypeMapping( typeConfiguration ); + } + private javax.persistence.EnumType getEnumType(ParameterType reader) { javax.persistence.EnumType enumType = null; if ( reader.isPrimaryKey() ) { @@ -157,26 +186,50 @@ public class EnumType } private EnumValueConverter interpretParameters(Properties parameters) { - final EnumJavaTypeDescriptor javaTypeDescriptor = (EnumJavaTypeDescriptor) typeConfiguration + final EnumJavaTypeDescriptor enumJavaDescriptor = (EnumJavaTypeDescriptor) typeConfiguration .getJavaTypeDescriptorRegistry() .getDescriptor( enumClass ); + + final ParameterType reader = (ParameterType) parameters.get( PARAMETER_TYPE ); + final javax.persistence.EnumType enumType = getEnumType( reader ); + final LocalSqlTypeDescriptorIndicators localIndicators = new LocalSqlTypeDescriptorIndicators( enumType, reader ); + + final BasicJavaDescriptor stringJavaDescriptor = (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( String.class ); + final BasicJavaDescriptor integerJavaDescriptor = (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Integer.class ); + if ( parameters.containsKey( NAMED ) ) { final boolean useNamed = ConfigurationHelper.getBoolean( NAMED, parameters ); if ( useNamed ) { - return new NamedEnumValueConverter( javaTypeDescriptor ); + return new NamedEnumValueConverter( + enumJavaDescriptor, + stringJavaDescriptor.getJdbcRecommendedSqlType( localIndicators ), + stringJavaDescriptor + ); } else { - return new OrdinalEnumValueConverter( javaTypeDescriptor ); + return new OrdinalEnumValueConverter( + enumJavaDescriptor, + integerJavaDescriptor.getJdbcRecommendedSqlType( localIndicators ), + (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Integer.class ) + ); } } if ( parameters.containsKey( TYPE ) ) { final int type = Integer.decode( (String) parameters.get( TYPE ) ); if ( isNumericType( type ) ) { - return new OrdinalEnumValueConverter( javaTypeDescriptor ); + return new OrdinalEnumValueConverter( + enumJavaDescriptor, + integerJavaDescriptor.getJdbcRecommendedSqlType( localIndicators ), + (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Integer.class ) + ); } else if ( isCharacterType( type ) ) { - return new NamedEnumValueConverter( javaTypeDescriptor ); + return new NamedEnumValueConverter( + enumJavaDescriptor, + stringJavaDescriptor.getJdbcRecommendedSqlType( localIndicators ), + stringJavaDescriptor + ); } else { throw new HibernateException( @@ -190,7 +243,11 @@ public class EnumType } // the fallback - return new OrdinalEnumValueConverter( javaTypeDescriptor ); + return new OrdinalEnumValueConverter( + enumJavaDescriptor, + integerJavaDescriptor.getJdbcRecommendedSqlType( localIndicators ), + (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Integer.class ) + ); } private boolean isCharacterType(int jdbcTypeCode) { @@ -306,24 +363,66 @@ public class EnumType @Override public String toXMLString(Object value) { verifyConfigured(); - return (String) enumValueConverter.getJavaDescriptor().unwrap( (Enum) value, String.class, null ); + return (String) enumValueConverter.getDomainJavaDescriptor().unwrap( (Enum) value, String.class, null ); } @Override @SuppressWarnings("RedundantCast") public Object fromXMLString(String xmlValue) { verifyConfigured(); - return (T) enumValueConverter.getJavaDescriptor().wrap( xmlValue, null ); + return (T) enumValueConverter.getDomainJavaDescriptor().wrap( xmlValue, null ); } @Override public String toLoggableString(Object value, SessionFactoryImplementor factory) { verifyConfigured(); - return enumValueConverter.getJavaDescriptor().toString( (Enum) value ); + return enumValueConverter.getDomainJavaDescriptor().toString( (Enum) value ); } public boolean isOrdinal() { verifyConfigured(); return enumValueConverter instanceof OrdinalEnumValueConverter; } + + private class LocalSqlTypeDescriptorIndicators implements SqlTypeDescriptorIndicators { + private final javax.persistence.EnumType enumType; + private final ParameterType reader; + + public LocalSqlTypeDescriptorIndicators(javax.persistence.EnumType enumType, ParameterType reader) { + this.enumType = enumType; + this.reader = reader; + } + + @Override + public TypeConfiguration getTypeConfiguration() { + return typeConfiguration; + } + + @Override + public javax.persistence.EnumType getEnumeratedType() { + if ( enumType != null ) { + return enumType; + } + return typeConfiguration.getCurrentBaseSqlTypeIndicators().getEnumeratedType(); + } + + @Override + public boolean isNationalized() { + return isNationalized( reader ); + } + + private boolean isNationalized(ParameterType reader) { + if ( typeConfiguration.getCurrentBaseSqlTypeIndicators().isNationalized() ) { + return true; + } + + for ( Annotation annotation : reader.getAnnotationsMethod() ) { + if ( annotation instanceof Nationalized ) { + return true; + } + } + + return false; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java index 04ba4399d3..771bef1e33 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptions.java @@ -11,6 +11,7 @@ import java.util.Calendar; import java.util.TimeZone; import org.hibernate.engine.jdbc.LobCreator; +import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** @@ -19,6 +20,12 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; * @author Steve Ebersole */ public interface WrapperOptions { + + /** + * Access to the current Session + */ + SharedSessionContractImplementor getSession(); + /** * Should streams be used for binding LOB values. * diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java deleted file mode 100644 index 0d354b499e..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.type.descriptor; - -/** - * Defines the context for {@link WrapperOptions} - * - * @author Steve Ebersole - * - * @deprecated (since 5.2) Just directly implement WrapperOptions - */ -@Deprecated -public interface WrapperOptionsContext extends WrapperOptions { - /** - * Obtain the WrapperOptions for this context. - * - * @return The WrapperOptions - * - * @deprecated (since 5.2) Just directly implement WrapperOptions - */ - @Deprecated - default WrapperOptions getWrapperOptions() { - return this; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java index 1b1039968f..0d74b51fea 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java @@ -6,7 +6,12 @@ */ package org.hibernate.type.descriptor.java; +import java.sql.Types; +import javax.persistence.EnumType; + import org.hibernate.type.descriptor.WrapperOptions; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators; /** * Describes a Java Enum type. @@ -17,7 +22,18 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript @SuppressWarnings("unchecked") public EnumJavaTypeDescriptor(Class type) { super( type, ImmutableMutabilityPlan.INSTANCE ); - //JavaTypeDescriptorRegistry.INSTANCE.addDescriptor( this ); + } + + @Override + public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) { + if ( context.getEnumeratedType() != null && context.getEnumeratedType() == EnumType.STRING ) { + return context.isNationalized() + ? context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.NVARCHAR ) + : context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.VARCHAR ); + } + else { + return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.INTEGER ); + } } @Override @@ -37,7 +53,7 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript if ( String.class.equals( type ) ) { return (X) toName( value ); } - else if ( Integer.class.isInstance( type ) ) { + else if ( Integer.class.equals( type ) ) { return (X) toOrdinal( value ); } @@ -50,10 +66,10 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript if ( value == null ) { return null; } - else if ( String.class.isInstance( value ) ) { + else if ( value instanceof String ) { return fromName( (String) value ); } - else if ( Integer.class.isInstance( value ) ) { + else if ( value instanceof Integer ) { return fromOrdinal( (Integer) value ); } @@ -61,6 +77,9 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript } + /** + * Convert a value of the enum type to its ordinal value + */ public Integer toOrdinal(E domainForm) { if ( domainForm == null ) { return null; @@ -68,6 +87,9 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript return domainForm.ordinal(); } + /** + * Interpret a numeric value as the ordinal of the enum type + */ @SuppressWarnings("unchecked") public E fromOrdinal(Integer relationalForm) { if ( relationalForm == null ) { @@ -76,6 +98,19 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript return (E) getJavaType().getEnumConstants()[ relationalForm ]; } + /** + * Convert a value of the enum type to its name value + */ + public String toName(T domainForm) { + if ( domainForm == null ) { + return null; + } + return domainForm.name(); + } + + /** + * Interpret a String value as the named value of the enum type + */ @SuppressWarnings("unchecked") public T fromName(String relationalForm) { if ( relationalForm == null ) { @@ -83,11 +118,4 @@ public class EnumJavaTypeDescriptor extends AbstractTypeDescript } return (T) Enum.valueOf( getJavaType(), relationalForm.trim() ); } - - public String toName(T domainForm) { - if ( domainForm == null ) { - return null; - } - return domainForm.name(); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EnumJavaDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EnumJavaDescriptor.java deleted file mode 100644 index 08f617b740..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/EnumJavaDescriptor.java +++ /dev/null @@ -1,99 +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.type.descriptor.java.spi; - -import java.sql.Types; -import javax.persistence.EnumType; - -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; -import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; -import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; -import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators; - -/** - * Describes a Java Enum type. - * - * @author Steve Ebersole - */ -public class EnumJavaDescriptor extends AbstractTypeDescriptor { - - @SuppressWarnings("unchecked") - public EnumJavaDescriptor(Class type) { - super( type, ImmutableMutabilityPlan.INSTANCE ); - } - - @Override - public SqlTypeDescriptor getJdbcRecommendedSqlType(SqlTypeDescriptorIndicators context) { - if ( context.getEnumeratedType() != null && context.getEnumeratedType() == EnumType.STRING ) { - return context.isNationalized() - ? context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.NVARCHAR ) - : context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.VARCHAR ); - } - else { - return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor( Types.INTEGER ); - } - } - - @Override - public String toString(E value) { - return value == null ? "" : value.name(); - } - - @Override - @SuppressWarnings("unchecked") - public E fromString(String string) { - return string == null ? null : (E) Enum.valueOf( getJavaType(), string ); - } - - @Override - @SuppressWarnings("unchecked") - public X unwrap(E value, Class type, WrapperOptions options) { - return (X) value; - } - - @Override - @SuppressWarnings("unchecked") - public E wrap(X value, WrapperOptions options) { - return (E) value; - } - - public Integer toOrdinal(E domainForm) { - if ( domainForm == null ) { - return null; - } - return domainForm.ordinal(); - } - - @SuppressWarnings("unchecked") - public E fromOrdinal(Integer relationalForm) { - if ( relationalForm == null ) { - return null; - } - return (E) getJavaType().getEnumConstants()[ relationalForm ]; - } - - @SuppressWarnings("unchecked") - public E fromName(String relationalForm) { - if ( relationalForm == null ) { - return null; - } - return (E) Enum.valueOf( getJavaType(), relationalForm ); - } - - public String toName(E domainForm) { - if ( domainForm == null ) { - return null; - } - return domainForm.name(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "(" + getJavaType().getName() + ")"; - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java index d5750c8c91..fcfb9153e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java @@ -14,6 +14,7 @@ import org.hibernate.boot.model.TypeContributor; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; +import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators; @@ -121,7 +122,7 @@ public class JavaTypeDescriptorRegistry implements JavaTypeDescriptorBaseline.Ba final JavaTypeDescriptor fallbackDescriptor; if ( javaType.isEnum() ) { - fallbackDescriptor = new EnumJavaDescriptor( javaType ); + fallbackDescriptor = new EnumJavaTypeDescriptor( javaType ); } else if ( Serializable.class.isAssignableFrom( javaType ) ) { fallbackDescriptor = new OnTheFlySerializableJavaDescriptor( javaType ); diff --git a/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java b/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java index b231059731..c3ae212365 100644 --- a/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java +++ b/hibernate-core/src/test/java/org/hibernate/engine/query/ParameterParserTest.java @@ -7,8 +7,8 @@ package org.hibernate.engine.query; import org.hibernate.engine.query.spi.ParamLocationRecognizer; -import org.hibernate.engine.query.spi.ParameterParser; -import org.hibernate.engine.query.spi.ParameterParser.Recognizer; +import org.hibernate.query.sql.internal.ParameterParser; +import org.hibernate.query.sql.spi.ParameterRecognizer; import org.hibernate.testing.TestForIssue; import org.junit.Test; @@ -24,13 +24,6 @@ import static org.junit.Assert.fail; * @author Steve Ebersole */ public class ParameterParserTest { - @Test - public void testEscapeCallRecognition() { - assertTrue( ParameterParser.startsWithEscapeCallTemplate( "{ ? = call abc(?) }" ) ); - assertFalse( ParameterParser.startsWithEscapeCallTemplate( - "from User u where u.userName = ? and u.userType = 'call'" - ) ); - } @Test public void testQuotedTextInComment() { ParamLocationRecognizer recognizer = new ParamLocationRecognizer( 0 ); @@ -38,6 +31,8 @@ public class ParameterParserTest { ParameterParser.parse("-- 'This' should not fail the test.\n" + "SELECT column FROM Table WHERE column <> :param", recognizer); + recognizer.validate(); + assertTrue(recognizer.getNamedParameterDescriptionMap().containsKey("param")); } @@ -82,7 +77,7 @@ public class ParameterParserTest { @TestForIssue( jiraKey = "HHH-1237") public void testParseColonCharacterEscaped() { final StringBuilder captured = new StringBuilder(); - Recognizer recognizer = new Recognizer() { + ParameterRecognizer recognizer = new ParameterRecognizer() { @Override public void outParameter(int position) { fail(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicComponentTuplizer.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicComponentTuplizer.java index 79f3c31ea1..f7ab3cf289 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicComponentTuplizer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicComponentTuplizer.java @@ -8,7 +8,7 @@ //$Id$ package org.hibernate.test.annotations.tuplizer; import org.hibernate.mapping.Component; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.component.PojoComponentTuplizer; /** diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicEntityTuplizer.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicEntityTuplizer.java index 9ecf824531..67b8fac473 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicEntityTuplizer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicEntityTuplizer.java @@ -10,7 +10,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.ProxyFactory; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.PojoEntityTuplizer; diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicInstantiator.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicInstantiator.java index 1c32910e38..563fc9cf9d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicInstantiator.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/DynamicInstantiator.java @@ -14,7 +14,7 @@ import java.lang.reflect.Proxy; import org.hibernate.HibernateException; import org.hibernate.internal.util.ReflectHelper; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; /** * @author Emmanuel Bernard diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyEntityInstantiator.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyEntityInstantiator.java index b264ff6331..ed1163d073 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyEntityInstantiator.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyEntityInstantiator.java @@ -9,7 +9,7 @@ package org.hibernate.test.annotations.tuplizer.bytebuddysubclass; import java.io.Serializable; import org.hibernate.mapping.PersistentClass; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import net.bytebuddy.ByteBuddy; import net.bytebuddy.implementation.FixedValue; diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyTuplizer.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyTuplizer.java index 971e32a170..e9241cfde0 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyTuplizer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/tuplizer/bytebuddysubclass/MyTuplizer.java @@ -8,7 +8,7 @@ package org.hibernate.test.annotations.tuplizer.bytebuddysubclass; import org.hibernate.EntityNameResolver; import org.hibernate.mapping.PersistentClass; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.PojoEntityTuplizer; diff --git a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityInstantiator.java b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityInstantiator.java index f509feb71c..6d240cf7e4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityInstantiator.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityInstantiator.java @@ -12,7 +12,7 @@ import java.lang.reflect.Proxy; import org.hibernate.HibernateException; import org.hibernate.internal.util.ReflectHelper; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.test.dynamicentity.Address; import org.hibernate.test.dynamicentity.Company; diff --git a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java index 2acf7ffc63..6784a58621 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java @@ -9,7 +9,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.property.access.spi.Getter; import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.ProxyFactory; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.PojoEntityTuplizer; diff --git a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java index 455050c6a3..e62c509fac 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java @@ -15,7 +15,7 @@ import org.hibernate.test.dynamicentity.Company; import org.hibernate.test.dynamicentity.Customer; import org.hibernate.test.dynamicentity.Person; import org.hibernate.test.dynamicentity.ProxyHelper; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; /** * @author Steve Ebersole diff --git a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java index 86586d67dd..224a2fea2f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java @@ -13,7 +13,7 @@ import org.hibernate.property.access.spi.Setter; import org.hibernate.proxy.ProxyFactory; import org.hibernate.test.dynamicentity.ProxyHelper; import org.hibernate.test.dynamicentity.tuplizer.MyEntityInstantiator; -import org.hibernate.tuple.Instantiator; +import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.PojoEntityTuplizer; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeAttributeResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeAttributeResultSetProcessorTest.java index 26cbe6a8d3..80a8776f8a 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeAttributeResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeAttributeResultSetProcessorTest.java @@ -31,14 +31,12 @@ import java.util.List; import org.hibernate.LockMode; import org.hibernate.Session; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.JoinWalker; import org.hibernate.loader.entity.EntityJoinWalker; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeIdResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeIdResultSetProcessorTest.java index 8e012efba2..bfa44c2555 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeIdResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EncapsulatedCompositeIdResultSetProcessorTest.java @@ -21,11 +21,9 @@ import javax.persistence.ManyToOne; import org.hibernate.LockOptions; import org.hibernate.Session; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityAssociationResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityAssociationResultSetProcessorTest.java index 62863406a5..34cc9dd600 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityAssociationResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityAssociationResultSetProcessorTest.java @@ -21,11 +21,9 @@ import java.util.List; import org.hibernate.Hibernate; import org.hibernate.Session; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyCollectionResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyCollectionResultSetProcessorTest.java index 6475d7a450..3ccb16e2b5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyCollectionResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyCollectionResultSetProcessorTest.java @@ -24,11 +24,9 @@ import java.util.Set; import org.hibernate.Hibernate; import org.hibernate.Session; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManyListResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManyListResultSetProcessorTest.java index a28ba716c6..ba84cc964f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManyListResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManyListResultSetProcessorTest.java @@ -22,11 +22,9 @@ import java.util.List; import org.hibernate.Hibernate; import org.hibernate.Session; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManySetResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManySetResultSetProcessorTest.java index b94f2c33fd..37c268d5a4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManySetResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/EntityWithNonLazyOneToManySetResultSetProcessorTest.java @@ -18,21 +18,17 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.hibernate.Hibernate; import org.hibernate.Session; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.param.ParameterBinder; import org.hibernate.persister.entity.EntityPersister; import org.junit.Test; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/Helper.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/Helper.java index 56862be56d..8bfeca56ed 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/Helper.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/Helper.java @@ -6,15 +6,9 @@ */ package org.hibernate.test.loadplans.process; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - import org.hibernate.LockMode; import org.hibernate.LockOptions; -import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.spi.LoadQueryInfluencers; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.plan.build.internal.FetchStyleLoadPlanBuildingAssociationVisitationStrategy; import org.hibernate.loader.plan.build.spi.MetamodelDrivenLoadPlanBuilder; @@ -24,7 +18,6 @@ import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.query.spi.QueryBuildingParameters; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; -import org.hibernate.param.ParameterBinder; import org.hibernate.persister.entity.EntityPersister; /** diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/NonEncapsulatedCompositeIdResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/NonEncapsulatedCompositeIdResultSetProcessorTest.java index 855f919d35..a84bc62ff3 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/NonEncapsulatedCompositeIdResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/NonEncapsulatedCompositeIdResultSetProcessorTest.java @@ -16,11 +16,9 @@ import java.util.List; import org.hibernate.LockOptions; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/SimpleResultSetProcessorTest.java b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/SimpleResultSetProcessorTest.java index c8f13e4979..69412f67fe 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/SimpleResultSetProcessorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/loadplans/process/SimpleResultSetProcessorTest.java @@ -17,11 +17,9 @@ import java.util.List; import org.hibernate.Session; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.jdbc.Work; import org.hibernate.loader.plan.exec.process.spi.ResultSetProcessor; -import org.hibernate.loader.plan.exec.query.spi.NamedParameterContext; import org.hibernate.loader.plan.exec.spi.LoadQueryDetails; import org.hibernate.loader.plan.spi.LoadPlan; import org.hibernate.persister.entity.EntityPersister; diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java index 8a9915c418..bfae866195 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/EntityInstantiator.java @@ -80,7 +80,7 @@ public class EntityInstantiator { .getFactory() .getEntityPersister( entityName ) .getEntityTuplizer() - .instantiate(); + .instantiate( null, versionsReader.getSession() ); // Putting the newly created entity instance into the first level cache, in case a one-to-one bidirectional // relation is present (which is eagerly loaded). diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImplementor.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImplementor.java index dbc09adf5d..3dad71853b 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImplementor.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/reader/AuditReaderImplementor.java @@ -6,7 +6,6 @@ */ package org.hibernate.envers.internal.reader; -import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.AuditReader; @@ -18,7 +17,7 @@ import org.hibernate.envers.AuditReader; public interface AuditReaderImplementor extends AuditReader { SessionImplementor getSessionImplementor(); - Session getSession(); + SessionImplementor getSession(); FirstLevelCache getFirstLevelCache(); }