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 4d0549acdf..18fb93df28 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,6 +8,7 @@ package org.hibernate.engine.query.internal; import org.hibernate.engine.query.spi.NativeQueryInterpreter; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.sql.internal.NativeSelectQueryPlanImpl; import org.hibernate.query.sql.internal.ParameterParser; import org.hibernate.query.sql.spi.NativeSelectQueryDefinition; @@ -36,7 +37,7 @@ public class NativeQueryInterpreterStandardImpl implements NativeQueryInterprete queryDefinition.getSqlString(), queryDefinition.getAffectedTableNames(), queryDefinition.getQueryParameterList(), - queryDefinition.getJdbcValuesMappingProducer(), + (ResultSetMapping) queryDefinition.getJdbcValuesMappingProducer(), queryDefinition.getRowTransformer(), sessionFactory ); 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 e8cc9942a6..0fe81832ad 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 @@ -9,6 +9,7 @@ package org.hibernate.engine.query.spi; import org.hibernate.Incubating; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.sql.internal.NativeSelectQueryPlanImpl; import org.hibernate.query.sql.spi.NativeNonSelectQueryDefinition; import org.hibernate.query.sql.spi.NativeNonSelectQueryPlan; @@ -45,7 +46,7 @@ public interface NativeQueryInterpreter extends Service { queryDefinition.getSqlString(), queryDefinition.getAffectedTableNames(), queryDefinition.getQueryParameterList(), - queryDefinition.getJdbcValuesMappingProducer(), + (ResultSetMapping) queryDefinition.getJdbcValuesMappingProducer(), queryDefinition.getRowTransformer(), sessionFactory ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java index 4411b82aa4..ff101f3c76 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java @@ -7,6 +7,7 @@ package org.hibernate.internal; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -151,12 +152,24 @@ public class FilterHelper { } } - public static FilterPredicate createFilterPredicate(LoadQueryInfluencers loadQueryInfluencers, Joinable joinable) { - return createFilterPredicate( loadQueryInfluencers, joinable, null ); + public static FilterPredicate createFilterPredicate( + LoadQueryInfluencers loadQueryInfluencers, + Joinable joinable, + TableGroup rootTableGroup) { + return createFilterPredicate( loadQueryInfluencers, joinable, rootTableGroup, true ); } - public static FilterPredicate createFilterPredicate(LoadQueryInfluencers loadQueryInfluencers, Joinable joinable, TableGroup rootTableGroup) { - final String filterFragment = joinable.filterFragment( rootTableGroup, loadQueryInfluencers.getEnabledFilters() ); + public static FilterPredicate createFilterPredicate( + LoadQueryInfluencers loadQueryInfluencers, + Joinable joinable, + TableGroup rootTableGroup, + boolean useIdentificationVariable) { + final String filterFragment = joinable.filterFragment( + rootTableGroup, + loadQueryInfluencers.getEnabledFilters(), + Collections.emptySet(), + useIdentificationVariable + ); if ( StringHelper.isNotEmpty( filterFragment ) ) { return doCreateFilterPredicate( filterFragment, loadQueryInfluencers.getEnabledFilters() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java index 566972bc2e..2d6cebbe00 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java @@ -101,7 +101,7 @@ class DatabaseSnapshotExecutor { state.getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup ); // We produce the same state array as if we were creating an entity snapshot - final List domainResults = new ArrayList<>(); + final List> domainResults = new ArrayList<>(); final SqlExpressionResolver sqlExpressionResolver = state.getSqlExpressionResolver(); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index 0446aac371..90bc600e31 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -95,44 +95,6 @@ import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnRefere public class LoaderSelectBuilder { private static final Logger log = Logger.getLogger( LoaderSelectBuilder.class ); - /** - * Create an SQL AST select-statement based on matching one-or-more keys - * - * @param loadable The root Loadable - * @param partsToSelect Parts of the Loadable to select. Null/empty indicates to select the Loadable itself - * @param restrictedPart Part to base the where-clause restriction on - * @param cachedDomainResult DomainResult to be used. Null indicates to generate the DomainResult - * @param numberOfKeysToLoad How many keys should be accounted for in the where-clause restriction? - * @param loadQueryInfluencers Any influencers (entity graph, fetch profile) to account for - * @param lockOptions Pessimistic lock options to apply - * @param jdbcParameterConsumer Consumer for all JdbcParameter references created - * @param sessionFactory The SessionFactory - */ - public static SelectStatement createSelect( - Loadable loadable, - List partsToSelect, - ModelPart restrictedPart, - DomainResult cachedDomainResult, - int numberOfKeysToLoad, - LoadQueryInfluencers loadQueryInfluencers, - LockOptions lockOptions, - Consumer jdbcParameterConsumer, - SessionFactoryImplementor sessionFactory) { - final LoaderSelectBuilder process = new LoaderSelectBuilder( - sessionFactory, - loadable, - partsToSelect, - restrictedPart, - cachedDomainResult, - numberOfKeysToLoad, - loadQueryInfluencers, - lockOptions, - jdbcParameterConsumer - ); - - return process.generateSelect(); - } - /** * Create an SQL AST select-statement for a select by unique key based on matching one-or-more keys * @@ -173,6 +135,44 @@ public class LoaderSelectBuilder { return process.generateSelect(); } + /** + * Create an SQL AST select-statement based on matching one-or-more keys + * + * @param loadable The root Loadable + * @param partsToSelect Parts of the Loadable to select. Null/empty indicates to select the Loadable itself + * @param restrictedPart Part to base the where-clause restriction on + * @param cachedDomainResult DomainResult to be used. Null indicates to generate the DomainResult + * @param numberOfKeysToLoad How many keys should be accounted for in the where-clause restriction? + * @param loadQueryInfluencers Any influencers (entity graph, fetch profile) to account for + * @param lockOptions Pessimistic lock options to apply + * @param jdbcParameterConsumer Consumer for all JdbcParameter references created + * @param sessionFactory The SessionFactory + */ + public static SelectStatement createSelect( + Loadable loadable, + List partsToSelect, + ModelPart restrictedPart, + DomainResult cachedDomainResult, + int numberOfKeysToLoad, + LoadQueryInfluencers loadQueryInfluencers, + LockOptions lockOptions, + Consumer jdbcParameterConsumer, + SessionFactoryImplementor sessionFactory) { + final LoaderSelectBuilder process = new LoaderSelectBuilder( + sessionFactory, + loadable, + partsToSelect, + restrictedPart, + cachedDomainResult, + numberOfKeysToLoad, + loadQueryInfluencers, + lockOptions, + jdbcParameterConsumer + ); + + return process.generateSelect(); + } + public static SelectStatement createSelect( Loadable loadable, List partsToSelect, @@ -444,6 +444,9 @@ public class LoaderSelectBuilder { applyFiltering( rootQuerySpec, rootTableGroup, pluralAttributeMapping ); applyOrdering( rootTableGroup, pluralAttributeMapping ); } + else if ( loadable instanceof Joinable ) { + applyFiltering( rootQuerySpec, rootTableGroup, (Joinable) loadable ); + } if ( orderByFragments != null ) { orderByFragments.forEach( @@ -455,7 +458,7 @@ public class LoaderSelectBuilder { ); } - return new SelectStatement( rootQuerySpec, (List) domainResults ); + return new SelectStatement( rootQuerySpec, domainResults ); } private void applyRestriction( @@ -575,6 +578,20 @@ public class LoaderSelectBuilder { } } + private void applyFiltering( + QuerySpec querySpec, + TableGroup tableGroup, + Joinable joinable) { + final Predicate filterPredicate = FilterHelper.createFilterPredicate( + loadQueryInfluencers, + joinable, + tableGroup + ); + if ( filterPredicate != null ) { + querySpec.applyPredicate( filterPredicate ); + } + } + private void applyOrdering(TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping) { if ( pluralAttributeMapping.getOrderByFragment() != null ) { applyOrdering( tableGroup, pluralAttributeMapping.getOrderByFragment() ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 9d28a20521..300ec520b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -1789,7 +1789,8 @@ public abstract class AbstractCollectionPersister buffer.append( " and " ); } assert elementPersister instanceof Joinable; - buffer.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, ( (Joinable) elementPersister ).getTableName() ) ); + final TableReference tableReference = tableGroup.getTableReference( ( (Joinable) elementPersister ).getTableName() ); + buffer.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, tableReference.getIdentificationVariable() ) ); } return buffer.toString(); @@ -1940,11 +1941,9 @@ public abstract class AbstractCollectionPersister public String filterFragment( TableGroup tableGroup, Map enabledFilters, - Set treatAsDeclarations) { - StringBuilder sessionFilterFragment = new StringBuilder(); - filterHelper.render( sessionFilterFragment, getFilterAliasGenerator( tableGroup ), enabledFilters ); - - TableReference tableReference = null; + Set treatAsDeclarations, + boolean useIdentificationVariable) { + TableReference tableReference; if ( isManyToMany() ) { // if filtering on many-to-many element were intended, getManyToManyFilterFragment() should have been chosen tableReference = tableGroup.getPrimaryTableReference(); @@ -1952,11 +1951,23 @@ public abstract class AbstractCollectionPersister else if ( elementPersister instanceof Joinable ) { tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), ( (Joinable) elementPersister ).getTableName() ); } - - if ( tableReference != null ) { - sessionFilterFragment.append( filterFragment( tableReference.getIdentificationVariable(), treatAsDeclarations ) ); + else { + tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), qualifiedTableName ); } - return sessionFilterFragment.toString(); + + final String alias; + if ( tableReference == null ) { + alias = null; + } + else if ( useIdentificationVariable && tableReference.getIdentificationVariable() != null ) { + alias = tableReference.getIdentificationVariable(); + } + else { + alias = tableReference.getTableExpression(); + } + StringBuilder sessionFilterFragment = new StringBuilder(); + filterHelper.render( sessionFilterFragment, getFilterAliasGenerator( tableGroup ), enabledFilters ); + return sessionFilterFragment.append( filterFragment( alias, treatAsDeclarations ) ).toString(); } @Override 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 8f5fa2dd17..289bd59633 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 @@ -4208,10 +4208,24 @@ public abstract class AbstractEntityPersister } @Override - public String filterFragment(TableGroup tableGroup, Map enabledFilters, Set treatAsDeclarations) { + public String filterFragment( + TableGroup tableGroup, + Map enabledFilters, + Set treatAsDeclarations, + boolean useIdentificationVariable) { + final String alias; + if ( tableGroup == null ) { + alias = null; + } + else if ( useIdentificationVariable && tableGroup.getPrimaryTableReference().getIdentificationVariable() != null ) { + alias = tableGroup.getPrimaryTableReference().getIdentificationVariable(); + } + else { + alias = tableGroup.getPrimaryTableReference().getTableExpression(); + } final StringBuilder sessionFilterFragment = new StringBuilder(); - filterHelper.render( sessionFilterFragment, tableGroup == null ? null : getFilterAliasGenerator( tableGroup ), enabledFilters ); - return sessionFilterFragment.append( filterFragment( tableGroup == null ? null : tableGroup.getPrimaryTableReference().getIdentificationVariable(), treatAsDeclarations ) ).toString(); + filterHelper.render( sessionFilterFragment, !useIdentificationVariable || tableGroup == null ? null : getFilterAliasGenerator( tableGroup ), enabledFilters ); + return sessionFilterFragment.append( filterFragment( alias, treatAsDeclarations ) ).toString(); } public String generateFilterConditionAlias(String rootAlias) { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java index 15ad920d05..a3f3aec5e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java @@ -85,16 +85,16 @@ public interface Joinable { return filterFragment( alias, enabledFilters, Collections.emptySet() ); } - public default String filterFragment(TableGroup tableGroup, Map enabledFilters) throws MappingException { - return filterFragment( tableGroup, enabledFilters, Collections.emptySet() ); - } - /** * Get the where clause filter, given a query alias and considering enabled session filters */ public String filterFragment(String alias, Map enabledFilters, Set treatAsDeclarations) throws MappingException; - public String filterFragment(TableGroup tableGroup, Map enabledFilters, Set treatAsDeclarations) throws MappingException; + public String filterFragment( + TableGroup tableGroup, + Map enabledFilters, + Set treatAsDeclarations, + boolean useIdentificationVariable) throws MappingException; public String oneToManyFilterFragment(String alias) throws MappingException; diff --git a/hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java b/hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java index 344fddcd65..7feeeafdf4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/NativeQuery.java @@ -26,7 +26,7 @@ import org.hibernate.FlushMode; import org.hibernate.LockMode; import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.model.domain.AllowableParameterType; import org.hibernate.metamodel.model.domain.BasicDomainType; import org.hibernate.transform.ResultTransformer; @@ -382,6 +382,15 @@ public interface NativeQuery extends Query, SynchronizeableQuery { * result sets. */ interface RootReturn extends ReturnableResultNode { + + String getTableAlias(); + + String getDiscriminatorAlias(); + + EntityMappingType getEntityMapping(); + + NavigablePath getNavigablePath(); + /** * Set the lock mode for this return. * @@ -391,10 +400,7 @@ public interface NativeQuery extends Query, SynchronizeableQuery { */ RootReturn setLockMode(LockMode lockMode); - default RootReturn addIdColumnAliases(String... aliases){ - throw new NotYetImplementedFor6Exception( getClass() ); - - } + RootReturn addIdColumnAliases(String... aliases); /** * Name the column alias that identifies the entity's discriminator. @@ -430,6 +436,13 @@ public interface NativeQuery extends Query, SynchronizeableQuery { * from result sets. */ interface FetchReturn extends ResultNode { + + String getTableAlias(); + + String getOwnerAlias(); + + String getFetchableName(); + /** * Set the lock mode for this return. * diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java b/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java index f98ffba1c6..173c3738c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/Builders.java @@ -13,6 +13,7 @@ import javax.persistence.metamodel.SingularAttribute; import org.hibernate.LockMode; import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.RuntimeMetamodels; import org.hibernate.metamodel.mapping.AttributeMapping; @@ -20,6 +21,7 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; +import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.query.NavigablePath; @@ -38,8 +40,12 @@ import org.hibernate.query.results.implicit.ImplicitFetchBuilderEmbeddable; import org.hibernate.query.results.implicit.ImplicitFetchBuilderEntity; import org.hibernate.query.results.implicit.ImplicitFetchBuilderPlural; import org.hibernate.query.results.implicit.ImplicitModelPartResultBuilderEntity; +import org.hibernate.sql.ast.spi.FromClauseAccess; +import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.results.graph.DomainResultCreationState; +import org.hibernate.sql.results.graph.FetchParent; import org.hibernate.sql.results.graph.Fetchable; +import org.hibernate.sql.results.graph.collection.internal.EntityCollectionPartTableGroup; import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable; import org.hibernate.sql.results.graph.entity.EntityValuedFetchable; import org.hibernate.type.BasicType; @@ -213,7 +219,7 @@ public class Builders { String tableAlias, String entityName, SessionFactoryImplementor sessionFactory) { - return entityCalculated( tableAlias, entityName, null,sessionFactory ); + return entityCalculated( tableAlias, entityName, null, sessionFactory ); } /** @@ -235,7 +241,7 @@ public class Builders { } public static DynamicFetchBuilderLegacy fetch(String tableAlias, String ownerTableAlias, String joinPropertyName) { - throw new NotYetImplementedFor6Exception( ); + return new DynamicFetchBuilderLegacy( tableAlias, ownerTableAlias, joinPropertyName, null ); } public static ResultBuilder implicitEntityResultBuilder( @@ -271,6 +277,28 @@ public class Builders { return new ImplicitFetchBuilderPlural( fetchPath, (PluralAttributeMapping) fetchable, creationState ); } + if ( fetchable instanceof EntityCollectionPart ) { + final EntityCollectionPart entityCollectionPart = (EntityCollectionPart) fetchable; + return (parent, fetchablePath, jdbcResultsMetadata, legacyFetchResolver, domainResultCreationState) -> { + final FromClauseAccess fromClauseAccess = domainResultCreationState.getSqlAstCreationState() + .getFromClauseAccess(); + final TableGroup collectionTableGroup = fromClauseAccess.findTableGroup( parent.getNavigablePath() ); + fromClauseAccess.registerTableGroup( + fetchablePath, + new EntityCollectionPartTableGroup( fetchablePath, collectionTableGroup, entityCollectionPart ) + ); + return parent.generateFetchableFetch( + entityCollectionPart, + fetchablePath, + FetchTiming.IMMEDIATE, + true, + LockMode.NONE, + null, + domainResultCreationState + ); + }; + } + throw new UnsupportedOperationException(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java index 3d155da707..a3d0adf4fe 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/DomainResultCreationStateImpl.java @@ -337,9 +337,24 @@ public class DomainResultCreationStateImpl final FetchBuilder explicitFetchBuilder = fetchBuilderResolverStack .getCurrent() .apply( relativePath.getFullPath() ); - final FetchBuilder fetchBuilder = explicitFetchBuilder != null - ? explicitFetchBuilder - : Builders.implicitFetchBuilder( fetchPath, fetchable, this ); + final FetchBuilder fetchBuilder; + if ( explicitFetchBuilder != null ) { + fetchBuilder = explicitFetchBuilder; + } + else { + final DynamicFetchBuilderLegacy fetchBuilderLegacy = legacyFetchResolver.resolve( + fromClauseAccess.findTableGroup( fetchParent.getNavigablePath() ) + .getPrimaryTableReference() + .getIdentificationVariable(), + fetchableName + ); + if ( fetchBuilderLegacy == null ) { + fetchBuilder = Builders.implicitFetchBuilder( fetchPath, fetchable, this ); + } + else { + fetchBuilder = fetchBuilderLegacy; + } + } final Fetch fetch = fetchBuilder.buildFetch( fetchParent, fetchPath, diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/JdbcValuesMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/JdbcValuesMappingImpl.java index a5e04117dc..d8c8b302a0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/JdbcValuesMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/JdbcValuesMappingImpl.java @@ -6,50 +6,30 @@ */ package org.hibernate.query.results; -import java.util.ArrayList; import java.util.List; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.sql.ast.spi.SqlSelection; -import org.hibernate.sql.results.graph.AssemblerCreationState; import org.hibernate.sql.results.graph.DomainResult; -import org.hibernate.sql.results.graph.DomainResultAssembler; -import org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping; +import org.hibernate.sql.results.jdbc.internal.StandardJdbcValuesMapping; /** * Implementation of JdbcValuesMapping for native / procedure queries * * @author Steve Ebersole */ -public class JdbcValuesMappingImpl implements JdbcValuesMapping { - private final List sqlSelections; - private final List> domainResults; +public class JdbcValuesMappingImpl extends StandardJdbcValuesMapping { + + private final int rowSize; public JdbcValuesMappingImpl( List sqlSelections, - List> domainResults) { - this.sqlSelections = sqlSelections; - this.domainResults = domainResults; + List> domainResults, int rowSize) { + super( sqlSelections, domainResults ); + this.rowSize = rowSize; } @Override - public List getSqlSelections() { - return sqlSelections; - } - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public List getDomainResults() { - return (List) domainResults; - } - - @Override - @SuppressWarnings("rawtypes") - public List resolveAssemblers(AssemblerCreationState creationState) { - final List assemblers = new ArrayList<>( domainResults.size() ); - domainResults.forEach( - domainResult -> assemblers.add( domainResult.createResultAssembler( creationState ) ) - ); - return assemblers; + public int getRowSize() { + return rowSize; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java index 673d1f31b0..4f3241c394 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMapping.java @@ -7,6 +7,7 @@ package org.hibernate.query.results; import java.util.function.BiConsumer; +import java.util.function.Consumer; import org.hibernate.Incubating; import org.hibernate.query.named.NamedResultSetMappingMemento; @@ -40,6 +41,7 @@ public interface ResultSetMapping extends JdbcValuesMappingProducer { int getNumberOfResultBuilders(); void visitResultBuilders(BiConsumer resultBuilderConsumer); + void visitLegacyFetchBuilders(Consumer resultBuilderConsumer); void addResultBuilder(ResultBuilder resultBuilder); void addLegacyFetchBuilder(DynamicFetchBuilderLegacy fetchBuilder); diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java index ee45831c4d..b7111a3df7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/ResultSetMappingImpl.java @@ -66,6 +66,19 @@ public class ResultSetMappingImpl implements ResultSetMapping { } } + @Override + public void visitLegacyFetchBuilders(Consumer resultBuilderConsumer) { + if ( legacyFetchBuilders == null ) { + return; + } + + for ( Map.Entry> entry : legacyFetchBuilders.entrySet() ) { + for ( DynamicFetchBuilderLegacy fetchBuilder : entry.getValue().values() ) { + resultBuilderConsumer.accept( fetchBuilder ); + } + } + } + @Override public void addResultBuilder(ResultBuilder resultBuilder) { if ( resultBuilders == null ) { @@ -120,15 +133,16 @@ public class ResultSetMappingImpl implements ResultSetMapping { SessionFactoryImplementor sessionFactory) { final int numberOfResults; + final int rowSize = jdbcResultsMetadata.getColumnCount(); if ( resultBuilders == null ) { - numberOfResults = jdbcResultsMetadata.getColumnCount(); + numberOfResults = rowSize; } else { numberOfResults = resultBuilders.size(); } - final List sqlSelections = new ArrayList<>( jdbcResultsMetadata.getColumnCount() ); + final List sqlSelections = new ArrayList<>( rowSize ); final List> domainResults = new ArrayList<>( numberOfResults ); final DomainResultCreationStateImpl creationState = new DomainResultCreationStateImpl( @@ -169,7 +183,7 @@ public class ResultSetMappingImpl implements ResultSetMapping { domainResults.add( domainResult ); } - return new JdbcValuesMappingImpl( sqlSelections, domainResults ); + return new JdbcValuesMappingImpl( sqlSelections, domainResults, rowSize ); } private DomainResult makeImplicitDomainResult( diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/TableGroupImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/TableGroupImpl.java index 762875be6e..2e063cc58d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/TableGroupImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/TableGroupImpl.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.results; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -28,7 +29,8 @@ public class TableGroupImpl implements TableGroup { private final NavigablePath navigablePath; private final String alias; - private final TableReferenceImpl primaryTableReference; + private final TableReference primaryTableReference; + private List tableGroupJoins; private final ModelPartContainer container; private final LockMode lockMode; @@ -37,7 +39,7 @@ public class TableGroupImpl implements TableGroup { public TableGroupImpl( NavigablePath navigablePath, String alias, - TableReferenceImpl primaryTableReference, + TableReference primaryTableReference, ModelPartContainer container, LockMode lockMode) { this.navigablePath = navigablePath; @@ -74,21 +76,29 @@ public class TableGroupImpl implements TableGroup { @Override public List getTableGroupJoins() { - return Collections.emptyList(); + return tableGroupJoins == null ? Collections.emptyList() : Collections.unmodifiableList( tableGroupJoins ); } @Override public boolean hasTableGroupJoins() { - return false; + return tableGroupJoins != null && !tableGroupJoins.isEmpty(); } @Override public void addTableGroupJoin(TableGroupJoin join) { - throw new UnsupportedOperationException(); + if ( tableGroupJoins == null ) { + tableGroupJoins = new ArrayList<>(); + } + if ( !tableGroupJoins.contains( join ) ) { + tableGroupJoins.add( join ); + } } @Override public void visitTableGroupJoins(Consumer consumer) { + if ( tableGroupJoins != null ) { + tableGroupJoins.forEach( consumer ); + } } @Override @@ -113,21 +123,28 @@ public class TableGroupImpl implements TableGroup { @Override public TableReference resolveTableReference(NavigablePath navigablePath, String tableExpression) { - return primaryTableReference; + final TableReference tableReference = getTableReference( navigablePath, tableExpression ); + if ( tableReference == null ) { + throw new IllegalStateException( "Could not resolve binding for table `" + tableExpression + "`" ); + } + + return tableReference; } @Override public TableReference getTableReference(NavigablePath navigablePath, String tableExpression) { - return primaryTableReference; + if ( primaryTableReference.getTableReference( navigablePath , tableExpression ) != null ) { + return primaryTableReference; + } + + for ( TableGroupJoin tableGroupJoin : getTableGroupJoins() ) { + final TableReference primaryTableReference = tableGroupJoin.getJoinedGroup().getPrimaryTableReference(); + if ( primaryTableReference.getTableReference( navigablePath, tableExpression ) != null ) { + return primaryTableReference; + } + } + + return null; } - public static class TableReferenceImpl extends TableReference { - public TableReferenceImpl( - String tableExpression, - String identificationVariable, - boolean isOptional, - SessionFactoryImplementor sessionFactory) { - super( tableExpression, identificationVariable, isOptional, sessionFactory ); - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicModelPart.java b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicModelPart.java index 03891a9aef..df85d1b4fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicModelPart.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicModelPart.java @@ -14,6 +14,7 @@ import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.DomainResultCreationState; @@ -65,13 +66,14 @@ public class CompleteResultBuilderBasicModelPart final TableReference tableReference = tableGroup.getTableReference( navigablePath, modelPart.getContainingTableExpression() ); final String mappedColumn = modelPart.getSelectionExpression(); - final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); - final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition ); - - creationStateImpl.resolveSqlSelection( + final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection( creationStateImpl.resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( tableReference, mappedColumn ), - processingState -> new SqlSelectionImpl( valuesArrayPosition, modelPart ) + processingState -> { + final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition ); + return new SqlSelectionImpl( valuesArrayPosition, modelPart ); + } ), modelPart.getJavaTypeDescriptor(), creationStateImpl.getSessionFactory().getTypeConfiguration() @@ -79,7 +81,7 @@ public class CompleteResultBuilderBasicModelPart //noinspection unchecked return new BasicResult( - valuesArrayPosition, + sqlSelection.getValuesArrayPosition(), columnAlias, modelPart.getJavaTypeDescriptor() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicValuedStandard.java b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicValuedStandard.java index bce2d37a92..400f1ab656 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicValuedStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/complete/CompleteResultBuilderBasicValuedStandard.java @@ -14,6 +14,7 @@ import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; @@ -54,39 +55,46 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB final DomainResultCreationStateImpl creationStateImpl = impl( domainResultCreationState ); final SessionFactoryImplementor sessionFactory = creationStateImpl.getSessionFactory(); - final int jdbcPosition; final String columnName; - if ( explicitColumnName != null ) { - jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( explicitColumnName ); columnName = explicitColumnName; } else { - jdbcPosition = resultPosition + 1; - columnName = jdbcResultsMetadata.resolveColumnName( jdbcPosition ); + columnName = jdbcResultsMetadata.resolveColumnName( resultPosition + 1 ); } - final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); - - final BasicValuedMapping basicType; - - if ( explicitType != null ) { - basicType = explicitType; - } - else { - basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor ); - } - - creationStateImpl.resolveSqlSelection( + final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection( creationStateImpl.resolveSqlExpression( columnName, - processingState -> new SqlSelectionImpl( valuesArrayPosition, basicType ) + processingState -> { + final int jdbcPosition; + if ( explicitColumnName != null ) { + jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( explicitColumnName ); + } + else { + jdbcPosition = resultPosition + 1; + } + final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); + + final BasicValuedMapping basicType; + if ( explicitType != null ) { + basicType = explicitType; + } + else { + basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor ); + } + return new SqlSelectionImpl( valuesArrayPosition, basicType ); + } ), explicitJavaTypeDescriptor, sessionFactory.getTypeConfiguration() ); - return new BasicResult<>( valuesArrayPosition, columnName, basicType.getMappedType().getMappedJavaTypeDescriptor() ); + return new BasicResult<>( + sqlSelection.getValuesArrayPosition(), + columnName, + sqlSelection.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaTypeDescriptor() + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/AbstractFetchBuilderContainer.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/AbstractFetchBuilderContainer.java index 43d30a1769..8156430120 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/AbstractFetchBuilderContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/AbstractFetchBuilderContainer.java @@ -72,4 +72,8 @@ public abstract class AbstractFetchBuilderContainer columnNames; + private final DynamicResultBuilderEntityStandard resultBuilderEntity; public DynamicFetchBuilderLegacy( String tableAlias, @@ -42,16 +57,33 @@ public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQue this.ownerTableAlias = ownerTableAlias; this.fetchableName = fetchableName; this.columnNames = columnNames; + this.resultBuilderEntity = null; } + public DynamicFetchBuilderLegacy( + String tableAlias, + String ownerTableAlias, + String fetchableName, + List columnNames, + DynamicResultBuilderEntityStandard resultBuilderEntity) { + this.tableAlias = tableAlias; + this.ownerTableAlias = ownerTableAlias; + this.fetchableName = fetchableName; + this.columnNames = columnNames; + this.resultBuilderEntity = resultBuilderEntity; + } + + @Override public String getTableAlias() { return tableAlias; } + @Override public String getOwnerAlias() { return ownerTableAlias; } + @Override public String getFetchableName() { return fetchableName; } @@ -64,12 +96,88 @@ public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQue BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { final DomainResultCreationStateImpl creationState = ResultsHelper.impl( domainResultCreationState ); - final TableGroup ownerTableGroup = creationState.getFromClauseAccess().findByAlias( ownerTableAlias ); + final AttributeMapping attributeMapping = parent.getReferencedMappingContainer() + .findContainingEntityMapping() + .findDeclaredAttributeMapping( fetchableName ); + final TableGroup tableGroup; + if ( attributeMapping instanceof TableGroupJoinProducer ) { + final SqlAliasBase sqlAliasBase = new SqlAliasBaseConstant( tableAlias ); + final TableGroupJoin tableGroupJoin = ( (TableGroupJoinProducer) attributeMapping ).createTableGroupJoin( + fetchPath, + ownerTableGroup, + tableAlias, + SqlAstJoinType.INNER, + true, + LockMode.NONE, + s -> sqlAliasBase, + creationState.getSqlExpressionResolver(), + creationState.getCreationContext() + ); + creationState.getFromClauseAccess().registerTableGroup( fetchPath, tableGroup = tableGroupJoin.getJoinedGroup() ); + } + else { + tableGroup = ownerTableGroup; + } - // todo (6.0) : create the TableGroupJoin for the fetch and then build the fetch + final ForeignKeyDescriptor keyDescriptor; + if ( attributeMapping instanceof PluralAttributeMapping ) { + final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) attributeMapping; + keyDescriptor = pluralAttributeMapping.getKeyDescriptor(); + } + else { + // Not sure if this fetch builder can also be used with other attribute mappings + assert attributeMapping instanceof ToOneAttributeMapping; - throw new NotYetImplementedFor6Exception( getClass() ); + final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping; + keyDescriptor = toOneAttributeMapping.getForeignKeyDescriptor(); + } + + keyDescriptor.forEachSelectable( + (selectionIndex, selectableMapping) -> { + resolveSqlSelection( + columnNames.get( selectionIndex ), + createColumnReferenceKey( + tableGroup.getTableReference( selectableMapping.getContainingTableExpression() ), + selectableMapping.getSelectionExpression() + ), + selectableMapping.getJdbcMapping(), + jdbcResultsMetadata, + domainResultCreationState + ); + } + ); + + // We process the fetch builder such that it contains a resultBuilderEntity before calling this method in ResultSetMappingProcessor + assert resultBuilderEntity != null; + + return resultBuilderEntity.buildFetch( + parent, + attributeMapping, + jdbcResultsMetadata, + creationState + ); + } + + private void resolveSqlSelection( + String columnAlias, + String columnKey, + JdbcMapping jdbcMapping, + JdbcValuesMetadata jdbcResultsMetadata, + DomainResultCreationState domainResultCreationState) { + final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); + sqlExpressionResolver.resolveSqlSelection( + sqlExpressionResolver.resolveSqlExpression( + columnKey, + state -> { + final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + final int valuesArrayPosition = jdbcPosition - 1; + return new SqlSelectionImpl( valuesArrayPosition, jdbcMapping ); + } + ), + jdbcMapping.getMappedJavaTypeDescriptor(), + domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration() + ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicFetchBuilderStandard.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicFetchBuilderStandard.java index 8bc42fccaf..f5a930c8e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicFetchBuilderStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicFetchBuilderStandard.java @@ -10,19 +10,30 @@ import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; -import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.LockMode; +import org.hibernate.engine.FetchTiming; +import org.hibernate.metamodel.mapping.BasicValuedMapping; +import org.hibernate.metamodel.mapping.SelectableConsumer; +import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.query.NativeQuery; import org.hibernate.query.NavigablePath; import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.ResultsHelper; +import org.hibernate.query.results.SqlSelectionImpl; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.Fetch; import org.hibernate.sql.results.graph.FetchParent; +import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; +import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; + /** * @author Steve Ebersole + * @author Christian Beikov */ public class DynamicFetchBuilderStandard implements DynamicFetchBuilder, NativeQuery.ReturnProperty { @@ -50,9 +61,59 @@ public class DynamicFetchBuilderStandard final TableGroup ownerTableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( parent.getNavigablePath() ); - // todo (6.0) : create the TableGroupJoin for the fetch and then build the fetch + final Fetchable attributeMapping = (Fetchable) parent.getReferencedMappingContainer().findSubPart( fetchableName, null ); + final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); - throw new NotYetImplementedFor6Exception( getClass() ); + final SelectableConsumer selectableConsumer = (selectionIndex, selectableMapping) -> { + final TableReference tableReference = ownerTableGroup.getTableReference( + fetchPath, + selectableMapping.getContainingTableExpression() + ); + final String columnAlias = columnNames.get( selectionIndex ); + sqlExpressionResolver.resolveSqlSelection( + sqlExpressionResolver.resolveSqlExpression( + createColumnReferenceKey( tableReference, selectableMapping.getSelectionExpression() ), + state -> { + final int resultSetPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + final int valuesArrayPosition = resultSetPosition - 1; + return new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) selectableMapping ); + } + ), + selectableMapping.getJdbcMapping().getMappedJavaTypeDescriptor(), + domainResultCreationState.getSqlAstCreationState() + .getCreationContext() + .getSessionFactory() + .getTypeConfiguration() + ); + }; + if ( attributeMapping instanceof BasicValuedMapping ) { + attributeMapping.forEachSelectable( selectableConsumer ); + return parent.generateFetchableFetch( + attributeMapping, + fetchPath, + FetchTiming.IMMEDIATE, + true, + LockMode.NONE, + null, + creationStateImpl + ); + } + else { + // Not sure if this fetch builder can also be used with other attribute mappings + assert attributeMapping instanceof ToOneAttributeMapping; + + final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping; + toOneAttributeMapping.getForeignKeyDescriptor().visitKeySelectables( selectableConsumer ); + return parent.generateFetchableFetch( + attributeMapping, + fetchPath, + FetchTiming.DELAYED, + false, + LockMode.NONE, + null, + creationStateImpl + ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderAttribute.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderAttribute.java index 3f9e33640e..7095c8ada3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderAttribute.java @@ -11,8 +11,10 @@ import java.util.function.BiFunction; import org.hibernate.metamodel.mapping.SingularAttributeMapping; import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; +import org.hibernate.query.NativeQuery; import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.basic.BasicResult; @@ -23,7 +25,7 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; * * @author Steve Ebersole */ -public class DynamicResultBuilderAttribute implements DynamicResultBuilder { +public class DynamicResultBuilderAttribute implements DynamicResultBuilder, NativeQuery.ReturnProperty { private final BasicAttributeMapping attributeMapping; private final String columnAlias; private final String entityName; @@ -53,29 +55,38 @@ public class DynamicResultBuilderAttribute implements DynamicResultBuilder { this.attributePath = attributePath; } + @Override + public NativeQuery.ReturnProperty addColumnAlias(String columnAlias) { + throw new UnsupportedOperationException(); + } + @Override public DomainResult buildResult( JdbcValuesMetadata jdbcResultsMetadata, int resultPosition, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { - final int resultSetPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); - final int valuesArrayPosition = resultSetPosition - 1; - // todo (6.0) : TableGroups + `attributeMapping#buldResult` final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); - sqlExpressionResolver.resolveSqlSelection( + final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( sqlExpressionResolver.resolveSqlExpression( columnAlias, - state -> new SqlSelectionImpl( valuesArrayPosition, attributeMapping ) + state -> { + final int resultSetPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + final int valuesArrayPosition = resultSetPosition - 1; + return new SqlSelectionImpl( valuesArrayPosition, attributeMapping ); + } ), attributeMapping.getJavaTypeDescriptor(), - domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration() + domainResultCreationState.getSqlAstCreationState() + .getCreationContext() + .getSessionFactory() + .getTypeConfiguration() ); return new BasicResult<>( - valuesArrayPosition, + sqlSelection.getValuesArrayPosition(), columnAlias, attributeMapping.getJavaTypeDescriptor(), attributeMapping.getValueConverter() diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicConverted.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicConverted.java index e9135cd364..713c010d57 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicConverted.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicConverted.java @@ -19,6 +19,7 @@ import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.resource.beans.spi.ProvidedInstanceManagedBeanImpl; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; @@ -97,32 +98,35 @@ public class DynamicResultBuilderBasicConverted implements DynamicResultBui int resultPosition, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { - final int currentJdbcPosition = resultPosition + 1; - - final int jdbcPosition; - if ( columnAlias != null ) { - jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); - } - else { - jdbcPosition = currentJdbcPosition; - } - final TypeConfiguration typeConfiguration = domainResultCreationState.getSqlAstCreationState() .getCreationContext() .getSessionFactory() .getTypeConfiguration(); - final BasicType basicType = jdbcResultsMetadata.resolveType( jdbcPosition, basicValueConverter.getRelationalJavaDescriptor() ); - - final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); - final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); - sqlExpressionResolver.resolveSqlExpression( - columnAlias, - state -> new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType ) + final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( + sqlExpressionResolver.resolveSqlExpression( + columnAlias, + state -> { + final int currentJdbcPosition = resultPosition + 1; + + final int jdbcPosition; + if ( columnAlias != null ) { + jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + } + else { + jdbcPosition = currentJdbcPosition; + } + final BasicType basicType = jdbcResultsMetadata.resolveType( jdbcPosition, basicValueConverter.getRelationalJavaDescriptor() ); + + final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); + return new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType ); + } + ), + domainJtd, + typeConfiguration ); - //noinspection unchecked - return new BasicResult( valuesArrayPosition, columnAlias, domainJtd, basicValueConverter ); + return new BasicResult<>( sqlSelection.getValuesArrayPosition(), columnAlias, domainJtd, basicValueConverter ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicStandard.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicStandard.java index 5e28ae3773..bfc7cfad47 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderBasicStandard.java @@ -13,6 +13,8 @@ import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.spi.SqlSelection; +import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; @@ -78,17 +80,24 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa .getCreationContext() .getSessionFactory(); - final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnName ); - final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); + final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); + final Expression expression = sqlExpressionResolver.resolveSqlExpression( + columnName, + state -> { + final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnName ); + final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition ); - final BasicType basicType; + final BasicType basicType; - if ( explicitType != null ) { - basicType = explicitType; - } - else { - basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor ); - } + if ( explicitType != null ) { + basicType = explicitType; + } + else { + basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor ); + } + return new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType ); + } + ); final JavaTypeDescriptor javaTypeDescriptor; @@ -96,23 +105,18 @@ public class DynamicResultBuilderBasicStandard implements DynamicResultBuilderBa javaTypeDescriptor = explicitJavaTypeDescriptor; } else { - javaTypeDescriptor = basicType.getJavaTypeDescriptor(); + javaTypeDescriptor = expression.getExpressionType().getJdbcMappings().get( 0 ).getMappedJavaTypeDescriptor(); } - - final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); - sqlExpressionResolver.resolveSqlSelection( - sqlExpressionResolver.resolveSqlExpression( - columnName, - state -> new SqlSelectionImpl( valuesArrayPosition, (BasicValuedMapping) basicType ) - ), - basicType.getJavaTypeDescriptor(), + final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( + expression, + javaTypeDescriptor, sessionFactory.getTypeConfiguration() ); // StandardRowReader expects there to be a JavaTypeDescriptor as part of the ResultAssembler. assert javaTypeDescriptor != null; - return new BasicResult<>( valuesArrayPosition, resultAlias, javaTypeDescriptor ); + return new BasicResult<>( sqlSelection.getValuesArrayPosition(), resultAlias, javaTypeDescriptor ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityCalculated.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityCalculated.java index 32289d2d42..c2d98eba0d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityCalculated.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityCalculated.java @@ -11,10 +11,13 @@ import java.util.function.BiFunction; import org.hibernate.LockMode; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.query.NativeQuery; import org.hibernate.query.NavigablePath; import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.TableGroupImpl; +import org.hibernate.sql.ast.spi.SqlAliasBaseConstant; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.DomainResultCreationState; import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; @@ -26,7 +29,7 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; * * @author Steve Ebersole */ -public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilderEntity { +public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilderEntity, NativeQuery.RootReturn { private final NavigablePath navigablePath; private final EntityMappingType entityMapping; @@ -47,6 +50,51 @@ public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilde this.sessionFactory = sessionFactory; } + @Override + public EntityMappingType getEntityMapping() { + return entityMapping; + } + + @Override + public String getTableAlias() { + return tableAlias; + } + + @Override + public NavigablePath getNavigablePath() { + return navigablePath; + } + + @Override + public NativeQuery.RootReturn setLockMode(LockMode lockMode) { + throw new UnsupportedOperationException(); + } + + @Override + public NativeQuery.RootReturn addIdColumnAliases(String... aliases) { + throw new UnsupportedOperationException(); + } + + @Override + public String getDiscriminatorAlias() { + return null; + } + + @Override + public NativeQuery.RootReturn setDiscriminatorAlias(String columnAlias) { + throw new UnsupportedOperationException(); + } + + @Override + public NativeQuery.RootReturn addProperty(String propertyName, String columnAlias) { + throw new UnsupportedOperationException(); + } + + @Override + public NativeQuery.ReturnProperty addProperty(String propertyName) { + throw new UnsupportedOperationException(); + } + @Override public EntityResult buildResult( JdbcValuesMetadata jdbcResultsMetadata, @@ -55,11 +103,10 @@ public class DynamicResultBuilderEntityCalculated implements DynamicResultBuilde DomainResultCreationState domainResultCreationState) { final DomainResultCreationStateImpl creationStateImpl = ResultsHelper.impl( domainResultCreationState ); - TableGroupImpl.TableReferenceImpl tableReference = new TableGroupImpl.TableReferenceImpl( - entityMapping.getEntityName(), - tableAlias, - false, - sessionFactory + final TableReference tableReference = entityMapping.createPrimaryTableReference( + new SqlAliasBaseConstant( tableAlias ), + creationStateImpl.getSqlExpressionResolver(), + creationStateImpl.getCreationContext() ); final TableGroupImpl tableGroup = new TableGroupImpl( diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityStandard.java b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityStandard.java index c1857df44a..12a1dc5045 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/dynamic/DynamicResultBuilderEntityStandard.java @@ -6,23 +6,48 @@ */ package org.hibernate.query.results.dynamic; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.function.BiFunction; +import java.util.function.Function; import org.hibernate.LockMode; -import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.FetchTiming; +import org.hibernate.metamodel.mapping.CollectionPart; +import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.query.NativeQuery; import org.hibernate.query.NavigablePath; +import org.hibernate.query.results.DomainResultCreationStateImpl; +import org.hibernate.query.results.SqlSelectionImpl; +import org.hibernate.query.results.TableGroupImpl; +import org.hibernate.sql.ast.spi.FromClauseAccess; +import org.hibernate.sql.ast.spi.SqlAliasBaseConstant; +import org.hibernate.sql.ast.spi.SqlExpressionResolver; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.results.graph.DomainResultCreationState; +import org.hibernate.sql.results.graph.Fetch; +import org.hibernate.sql.results.graph.FetchParent; +import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.entity.EntityResult; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata; +import static org.hibernate.query.results.ResultsHelper.impl; +import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey; + /** * @author Steve Ebersole + * @author Christian Beikov */ public class DynamicResultBuilderEntityStandard extends AbstractFetchBuilderContainer implements DynamicResultBuilderEntity, NativeQuery.RootReturn { + + private static final String ELEMENT_PREFIX = CollectionPart.Nature.ELEMENT.getName() + "."; + private final NavigablePath navigablePath; private final EntityMappingType entityMapping; @@ -30,28 +55,51 @@ public class DynamicResultBuilderEntityStandard private LockMode lockMode; + private List idColumnNames; private String discriminatorColumnName; public DynamicResultBuilderEntityStandard(EntityMappingType entityMapping, String tableAlias) { - this( entityMapping, tableAlias, null ); + this( entityMapping, tableAlias, new NavigablePath( entityMapping.getEntityName() ) ); } public DynamicResultBuilderEntityStandard( EntityMappingType entityMapping, String tableAlias, - String discriminatorColumnName) { - this.navigablePath = new NavigablePath( entityMapping.getEntityName() ); - + NavigablePath navigablePath) { + this.navigablePath = navigablePath; this.entityMapping = entityMapping; this.tableAlias = tableAlias; - - this.discriminatorColumnName = discriminatorColumnName; } + @Override public EntityMappingType getEntityMapping() { return entityMapping; } + @Override + public String getTableAlias() { + return tableAlias; + } + + @Override + public NavigablePath getNavigablePath() { + return navigablePath; + } + + @Override + public NativeQuery.RootReturn addIdColumnAliases(String... aliases) { + if ( idColumnNames == null ) { + idColumnNames = new ArrayList<>( aliases.length ); + } + Collections.addAll( idColumnNames, aliases ); + return this; + } + + @Override + public String getDiscriminatorAlias() { + return discriminatorColumnName; + } + @Override protected String getPropertyBase() { return entityMapping.getEntityName(); @@ -63,57 +111,135 @@ public class DynamicResultBuilderEntityStandard int resultPosition, BiFunction legacyFetchResolver, DomainResultCreationState domainResultCreationState) { -// final FromClauseAccessImpl fromClauseAccess = ResultsHelper.extractFromClauseAccess( domainResultCreationState ); -// final TableGroup tableGroup = fromClauseAccess.resolveTableGroup( -// navigablePath, -// np -> { -// final TableGroupImpl.TableReferenceImpl tableReference = new TableGroupImpl.TableReferenceImpl( -// entityMapping.getEntityName(), -// tableAlias, -// false, -// domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory() -// ); -// return new TableGroupImpl( navigablePath, tableAlias, tableReference, entityMapping, lockMode ); -// } -// ); -// -// return new EntityResultImpl( -// entityMapping, -// tableAlias, -// lockMode, -// jdbcResultsMetadata, -// sqlSelectionConsumer, -// () -> { -// if ( discriminatorColumnName == null ) { -// return null; -// } -// -// final int jdbcPosition; -// try { -// jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( discriminatorColumnName ); -// } -// catch (Exception e) { -// return null; -// } -// -// final int valuesArrayPosition = jdbcPosition - 1; -// -// final SqlSelection discriminatorSqlSelection = new SqlSelectionImpl( -// valuesArrayPosition, -// entityMapping.getDiscriminatorMapping() -// ); -// -// sqlSelectionConsumer.accept( discriminatorSqlSelection ); -// -// return discriminatorSqlSelection; -// }, -// // fetchableName -> fetchBuilders.get( fetchableName ), -// fetchableName -> null, -// legacyFetchResolver, -// domainResultCreationState -// ); + return buildResultOrFetch( + (tableGroup) -> (EntityResult) entityMapping.createDomainResult( + navigablePath, + tableGroup, + tableAlias, + domainResultCreationState + ), + jdbcResultsMetadata, + domainResultCreationState + ); + } - throw new NotYetImplementedFor6Exception( getClass() ); + public Fetch buildFetch( + FetchParent parent, + Fetchable fetchable, + JdbcValuesMetadata jdbcResultsMetadata, + DomainResultCreationState domainResultCreationState) { + return buildResultOrFetch( + (tableGroup) -> parent.generateFetchableFetch( + fetchable, + navigablePath, + FetchTiming.IMMEDIATE, + true, + lockMode, + null, + domainResultCreationState + ), + jdbcResultsMetadata, + domainResultCreationState + ); + } + + private T buildResultOrFetch( + Function resultOrFetchBuilder, + JdbcValuesMetadata jdbcResultsMetadata, + DomainResultCreationState domainResultCreationState) { + final DomainResultCreationStateImpl creationState = impl( domainResultCreationState ); + final FromClauseAccess fromClauseAccess = domainResultCreationState.getSqlAstCreationState().getFromClauseAccess(); + final TableGroup tableGroup = fromClauseAccess.resolveTableGroup( + navigablePath, + np -> { + final TableReference tableReference = entityMapping.createPrimaryTableReference( + new SqlAliasBaseConstant( tableAlias ), + creationState.getSqlExpressionResolver(), + creationState.getCreationContext() + ); + return new TableGroupImpl( navigablePath, tableAlias, tableReference, entityMapping, lockMode ); + } + ); + final TableReference tableReference = tableGroup.getPrimaryTableReference(); + + if ( idColumnNames != null ) { + final EntityIdentifierMapping identifierMapping = entityMapping.getIdentifierMapping(); + identifierMapping.forEachSelectable( + (selectionIndex, selectableMapping) -> { + resolveSqlSelection( + idColumnNames.get( selectionIndex ), + createColumnReferenceKey( tableReference, selectableMapping.getSelectionExpression() ), + selectableMapping.getJdbcMapping(), + jdbcResultsMetadata, + domainResultCreationState + ); + } + ); + } + + if ( discriminatorColumnName != null ) { + resolveSqlSelection( + discriminatorColumnName, + createColumnReferenceKey( + tableReference, + entityMapping.getDiscriminatorMapping().getSelectionExpression() + ), + entityMapping.getDiscriminatorMapping().getJdbcMapping(), + jdbcResultsMetadata, + domainResultCreationState + ); + } + + try { + final NavigablePath currentRelativePath = creationState.getCurrentRelativePath(); + final String prefix; + if ( currentRelativePath == null ) { + prefix = ""; + } + else { + prefix = currentRelativePath.getFullPath() + "."; + } + creationState.pushExplicitFetchMementoResolver( + relativePath -> { + if ( relativePath.startsWith( prefix ) ) { + final int startIndex; + if ( relativePath.regionMatches( prefix.length(), ELEMENT_PREFIX, 0, ELEMENT_PREFIX.length() ) ) { + startIndex = prefix.length() + ELEMENT_PREFIX.length(); + } + else { + startIndex = prefix.length(); + } + return findFetchBuilder( relativePath.substring( startIndex ) ); + } + return null; + } + ); + return resultOrFetchBuilder.apply( tableGroup ); + } + finally { + creationState.popExplicitFetchMementoResolver(); + } + } + + private void resolveSqlSelection( + String columnAlias, + String columnKey, + JdbcMapping jdbcMapping, + JdbcValuesMetadata jdbcResultsMetadata, + DomainResultCreationState domainResultCreationState) { + final SqlExpressionResolver sqlExpressionResolver = domainResultCreationState.getSqlAstCreationState().getSqlExpressionResolver(); + sqlExpressionResolver.resolveSqlSelection( + sqlExpressionResolver.resolveSqlExpression( + columnKey, + state -> { + final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias ); + final int valuesArrayPosition = jdbcPosition - 1; + return new SqlSelectionImpl( valuesArrayPosition, jdbcMapping ); + } + ), + jdbcMapping.getMappedJavaTypeDescriptor(), + domainResultCreationState.getSqlAstCreationState().getCreationContext().getSessionFactory().getTypeConfiguration() + ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java b/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java index 06d0828693..6973bb19ce 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/implicit/ImplicitFetchBuilderBasic.java @@ -17,6 +17,7 @@ import org.hibernate.query.results.DomainResultCreationStateImpl; import org.hibernate.query.results.ResultsHelper; import org.hibernate.query.results.SqlSelectionImpl; import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; +import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.results.graph.DomainResultCreationState; @@ -55,15 +56,16 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder { final String column = fetchable.getSelectionExpression(); final String table = fetchable.getContainingTableExpression(); - final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( column ); - final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition ); - final Expression expression = creationStateImpl.resolveSqlExpression( createColumnReferenceKey( parentTableGroup.getTableReference( fetchPath, table ), column ), - processingState -> new SqlSelectionImpl( valuesArrayPosition, fetchable ) + processingState -> { + final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( column ); + final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition ); + return new SqlSelectionImpl( valuesArrayPosition, fetchable ); + } ); - creationStateImpl.resolveSqlSelection( + final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection( expression, fetchable.getJavaTypeDescriptor(), domainResultCreationState.getSqlAstCreationState() @@ -81,7 +83,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder { } return new BasicFetch<>( - valuesArrayPosition, + sqlSelection.getValuesArrayPosition(), parent, fetchPath, fetchable, 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 index d91e614bba..9dd37b82b4 100644 --- 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 @@ -18,6 +18,7 @@ import org.hibernate.internal.EmptyScrollableResults; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.model.domain.AllowableParameterType; +import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterImplementor; @@ -53,12 +54,14 @@ public class NativeSelectQueryPlanImpl implements NativeSelectQueryPlan { String sql, Set affectedTableNames, List> parameterList, - JdbcValuesMappingProducer resultSetMapping, + ResultSetMapping resultSetMapping, RowTransformer rowTransformer, SessionFactoryImplementor sessionFactory) { - this.sql = sql; + final ResultSetMappingProcessor processor = new ResultSetMappingProcessor( resultSetMapping, sessionFactory ); + final SQLQueryParser parser = new SQLQueryParser( sql, processor.process(), sessionFactory ); + this.sql = parser.process(); this.parameterList = parameterList; - this.resultSetMapping = resultSetMapping; + this.resultSetMapping = processor.generateResultMapping( parser.queryHasAliases() ); this.rowTransformer = rowTransformer != null ? rowTransformer : RowTransformerPassThruImpl.instance(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java new file mode 100644 index 0000000000..a355536f4e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java @@ -0,0 +1,466 @@ +/* + * 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.query.sql.internal; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.hibernate.HibernateException; +import org.hibernate.MappingException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.loader.internal.AliasConstantsHelper; +import org.hibernate.metamodel.mapping.EntityMappingType; +import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.collection.SQLLoadableCollection; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.persister.entity.SQLLoadable; +import org.hibernate.query.NativeQuery; +import org.hibernate.query.NavigablePath; +import org.hibernate.query.results.ResultSetMapping; +import org.hibernate.query.results.ResultSetMappingImpl; +import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy; +import org.hibernate.query.results.dynamic.DynamicResultBuilderEntityStandard; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; + +/** + * Responsible for processing the {@link ResultSetMapping} + * defined by a {@link org.hibernate.query.sql.spi.NativeSelectQueryDefinition} and + * pre-process it for consumption in {@link SQLQueryParser}. + * + * @author Gavin King + * @author Max Andersen + * @author Steve Ebersole + */ +public class ResultSetMappingProcessor implements SQLQueryParser.ParserContext { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( ResultSetMappingProcessor.class ); + + private final ResultSetMapping resultSetMapping; + + private final Map alias2Return = new HashMap<>(); + private final Map alias2OwnerAlias = new HashMap<>(); + + private final Map alias2Persister = new HashMap<>(); + private final Map alias2Suffix = new HashMap<>(); + + private final Map alias2CollectionPersister = new HashMap<>(); + private final Map alias2CollectionSuffix = new HashMap<>(); + + private final Map> entityPropertyResultMaps = new HashMap<>(); + private final Map> collectionPropertyResultMaps = new HashMap<>(); + + private final SessionFactoryImplementor factory; + + private int entitySuffixSeed; + private int collectionSuffixSeed; + + + public ResultSetMappingProcessor(ResultSetMapping resultSetMapping, SessionFactoryImplementor factory) { + this.resultSetMapping = resultSetMapping; + this.factory = factory; + } + + private Map internalGetPropertyResultsMap(String alias) { + Map propertyResultMaps = collectionPropertyResultMaps.get( alias ); + if ( propertyResultMaps == null ) { + propertyResultMaps = entityPropertyResultMaps.get( alias ); + } + if ( propertyResultMaps != null ) { + return propertyResultMaps; + } + NativeQuery.ResultNode rtn = alias2Return.get( alias ); + if ( rtn instanceof NativeQuery.ReturnProperty && !( rtn instanceof NativeQuery.FetchReturn ) ) { + return null; + } + else { + // todo (6.0): access property results map somehow which was on NativeSQLQueryNonScalarReturn before + return Collections.emptyMap(); + } + } + + private boolean hasPropertyResultMap(String alias) { + Map propertyMaps = internalGetPropertyResultsMap( alias ); + return propertyMaps != null && ! propertyMaps.isEmpty(); + } + + public SQLQueryParser.ParserContext process() { + // first, break down the returns into maps keyed by alias + // so that role returns can be more easily resolved to their owners + resultSetMapping.visitResultBuilders( + (i, resultBuilder) -> { + if ( resultBuilder instanceof NativeQuery.RootReturn ) { + final NativeQuery.RootReturn rootReturn = (NativeQuery.RootReturn) resultBuilder; + alias2Return.put( rootReturn.getTableAlias(), rootReturn ); + } + } + ); + resultSetMapping.visitLegacyFetchBuilders( + fetchBuilder -> { + alias2Return.put( fetchBuilder.getTableAlias(), fetchBuilder ); + alias2OwnerAlias.put( fetchBuilder.getTableAlias(), fetchBuilder.getOwnerAlias() ); + } + ); + + // Now, process the returns + for ( NativeQuery.ResultNode queryReturn : alias2Return.values() ) { + processReturn( queryReturn ); + } + + return this; + } + + public ResultSetMapping generateResultMapping(boolean queryHadAliases) { + if ( !queryHadAliases ) { + return this.resultSetMapping; + } + final ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl( null ); + final Set visited = new HashSet<>(); + this.resultSetMapping.visitResultBuilders( + (i, resultBuilder) -> { + if ( resultBuilder instanceof NativeQuery.RootReturn ) { + final NativeQuery.RootReturn rootReturn = (NativeQuery.RootReturn) resultBuilder; + final String suffix = alias2Suffix.get( rootReturn.getTableAlias() ); + visited.add( rootReturn.getTableAlias() ); + if ( suffix == null ) { + resultSetMapping.addResultBuilder( resultBuilder ); + } + else { + final DynamicResultBuilderEntityStandard resultBuilderEntity = createSuffixedResultBuilder( + rootReturn, + suffix + ); + + resultSetMapping.addResultBuilder( resultBuilderEntity ); + alias2Return.put( rootReturn.getTableAlias(), resultBuilderEntity ); + } + } + else { + resultSetMapping.addResultBuilder( resultBuilder ); + } + } + ); + this.resultSetMapping.visitLegacyFetchBuilders( + fetchBuilder -> applyFetchBuilder( resultSetMapping, fetchBuilder, visited ) + ); + return resultSetMapping; + } + + private void applyFetchBuilder( + ResultSetMappingImpl resultSetMapping, + DynamicFetchBuilderLegacy fetchBuilder, + Set visited) { + if ( !visited.add( fetchBuilder.getTableAlias() ) ) { + return; + } + final String suffix = alias2Suffix.get( fetchBuilder.getTableAlias() ); + if ( suffix == null ) { + resultSetMapping.addLegacyFetchBuilder( fetchBuilder ); + } + else { + if ( !visited.contains( fetchBuilder.getOwnerAlias() ) ) { + applyFetchBuilder( + resultSetMapping, + // At this point, only legacy fetch builders weren't visited + (DynamicFetchBuilderLegacy) alias2Return.get( fetchBuilder.getOwnerAlias() ), + visited + ); + } + // At this point, the owner builder must be a DynamicResultBuilderEntityStandard to which we can add this builder to + final DynamicResultBuilderEntityStandard ownerBuilder = (DynamicResultBuilderEntityStandard) alias2Return.get( + fetchBuilder.getOwnerAlias() + ); + final DynamicResultBuilderEntityStandard resultBuilderEntity = createSuffixedResultBuilder( + alias2Persister.get( fetchBuilder.getTableAlias() ).findContainingEntityMapping(), + fetchBuilder.getTableAlias(), + suffix, + determineNavigablePath( fetchBuilder ) + ); + final SQLLoadable loadable = (SQLLoadable) alias2Persister.get( fetchBuilder.getOwnerAlias() ); + final List columnNames; + final String[] columnAliases = loadable.getSubclassPropertyColumnAliases( + fetchBuilder.getFetchableName(), + suffix + ); + if ( columnAliases.length == 0 ) { + final CollectionPersister collectionPersister = alias2CollectionPersister.get( fetchBuilder.getTableAlias() ); + if ( collectionPersister == null ) { + columnNames = Collections.emptyList(); + } + else { + columnNames = Arrays.asList( collectionPersister.getKeyColumnAliases( suffix ) ); + } + } + else { + columnNames = Arrays.asList( columnAliases ); + } + ownerBuilder.addFetchBuilder( + fetchBuilder.getFetchableName(), + new DynamicFetchBuilderLegacy( + fetchBuilder.getTableAlias(), + fetchBuilder.getOwnerAlias(), + fetchBuilder.getFetchableName(), + columnNames, + resultBuilderEntity + ) + ); +// resultSetMapping.addResultBuilder( resultBuilderEntity ); + alias2Return.put( fetchBuilder.getTableAlias(), resultBuilderEntity ); + } + } + + private NavigablePath determineNavigablePath(DynamicFetchBuilderLegacy fetchBuilder) { + final NativeQuery.ResultNode ownerResult = alias2Return.get( fetchBuilder.getOwnerAlias() ); + if ( ownerResult instanceof NativeQuery.RootReturn ) { + return ( (NativeQuery.RootReturn) ownerResult ).getNavigablePath() + .append( fetchBuilder.getFetchableName() ); + } + else { + return determineNavigablePath( ( DynamicFetchBuilderLegacy) ownerResult ) + .append( fetchBuilder.getFetchableName() ); + } + } + + private DynamicResultBuilderEntityStandard createSuffixedResultBuilder( + NativeQuery.RootReturn rootReturn, + String suffix) { + return createSuffixedResultBuilder( + rootReturn.getEntityMapping(), + rootReturn.getTableAlias(), + suffix, + new NavigablePath( rootReturn.getEntityMapping().getEntityName() ) + ); + } + + private DynamicResultBuilderEntityStandard createSuffixedResultBuilder( + EntityMappingType entityMapping, + String tableAlias, + String suffix, + NavigablePath navigablePath) { + final SQLLoadable loadable = (SQLLoadable) entityMapping.getEntityPersister(); + final DynamicResultBuilderEntityStandard resultBuilderEntity = new DynamicResultBuilderEntityStandard( + entityMapping, + tableAlias, + navigablePath + ); + + resultBuilderEntity.addIdColumnAliases( loadable.getIdentifierAliases( suffix ) ); + resultBuilderEntity.setDiscriminatorAlias( loadable.getDiscriminatorAlias( suffix ) ); + + for ( String propertyName : loadable.getPropertyNames() ) { + final String[] columnAliases = loadable.getSubclassPropertyColumnAliases( + propertyName, + suffix + ); + if ( columnAliases.length != 0 ) { + resultBuilderEntity.addProperty( + propertyName, + columnAliases + ); + } + } + return resultBuilderEntity; + } + + private SQLLoadable getSQLLoadable(String entityName) throws MappingException { + EntityPersister persister = factory.getEntityPersister( entityName ); + if ( !(persister instanceof SQLLoadable) ) { + throw new MappingException( "class persister is not SQLLoadable: " + entityName ); + } + return (SQLLoadable) persister; + } + + private String generateEntitySuffix() { + return AliasConstantsHelper.get( entitySuffixSeed++ ); + } + + private String generateCollectionSuffix() { + return collectionSuffixSeed++ + "__"; + } + + private void processReturn(NativeQuery.ResultNode rtn) { + if ( rtn instanceof NativeQuery.RootReturn ) { + processRootReturn( ( NativeQuery.RootReturn ) rtn ); + } + else if ( rtn instanceof NativeQuery.FetchReturn ) { + processFetchReturn( (NativeQuery.FetchReturn) rtn ); + } + else if ( rtn instanceof NativeQuery.InstantiationResultNode ) { + processConstructorReturn( (NativeQuery.InstantiationResultNode) rtn ); + } + else if ( rtn instanceof NativeQuery.ReturnProperty ) { + processScalarReturn( ( NativeQuery.ReturnProperty ) rtn ); + } + else if ( rtn instanceof NativeQuery.ReturnableResultNode ) { + } + else { + throw new IllegalStateException( + "Unrecognized NativeSQLQueryReturn concrete type encountered : " + rtn + ); + } + } + + private void processConstructorReturn(NativeQuery.InstantiationResultNode rtn) { + + } + + private void processScalarReturn(NativeQuery.ReturnProperty typeReturn) { +// scalarColumnAliases.add( typeReturn.getColumnAlias() ); +// scalarTypes.add( typeReturn.getType() ); + } + + private void processRootReturn(NativeQuery.RootReturn rootReturn) { + if ( alias2Persister.containsKey( rootReturn.getTableAlias() ) ) { + // already been processed... + return; + } + + SQLLoadable persister = (SQLLoadable) rootReturn.getEntityMapping().getEntityPersister(); + Map propertyResultsMap = Collections.emptyMap();//rootReturn.getPropertyResultsMap() + addPersister( rootReturn.getTableAlias(), propertyResultsMap, persister ); + } + + private void addPersister(String alias, Map propertyResult, SQLLoadable persister) { + alias2Persister.put( alias, persister ); + String suffix = generateEntitySuffix(); + LOG.tracev( "Mapping alias [{0}] to entity-suffix [{1}]", alias, suffix ); + alias2Suffix.put( alias, suffix ); + entityPropertyResultMaps.put( alias, propertyResult ); + } + + private void addCollection(String role, String alias, Map propertyResults) { + SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role ); + alias2CollectionPersister.put( alias, collectionPersister ); + String suffix = generateCollectionSuffix(); + LOG.tracev( "Mapping alias [{0}] to collection-suffix [{1}]", alias, suffix ); + alias2CollectionSuffix.put( alias, suffix ); + collectionPropertyResultMaps.put( alias, propertyResults ); + + if ( collectionPersister.isOneToMany() || collectionPersister.isManyToMany() ) { + SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister(); + addPersister( alias, filter( propertyResults ), persister ); + } + } + + private Map filter(Map propertyResults) { + final Map result = new HashMap<>( propertyResults.size() ); + final String keyPrefix = "element."; + + for ( Map.Entry element : propertyResults.entrySet() ) { + final String path = element.getKey(); + if ( path.startsWith( keyPrefix ) ) { + result.put( path.substring( keyPrefix.length() ), element.getValue() ); + } + } + + return result; + } + + private void processFetchReturn(NativeQuery.FetchReturn fetchReturn) { + String alias = fetchReturn.getTableAlias(); + if ( alias2Persister.containsKey( alias ) || alias2CollectionPersister.containsKey( alias ) ) { + // already been processed... + return; + } + + String ownerAlias = fetchReturn.getOwnerAlias(); + + // Make sure the owner alias is known... + if ( !alias2Return.containsKey( ownerAlias ) ) { + throw new HibernateException( "Owner alias [" + ownerAlias + "] is unknown for alias [" + alias + "]" ); + } + + // If this return's alias has not been processed yet, do so before further processing of this return + if ( !alias2Persister.containsKey( ownerAlias ) ) { + processReturn( alias2Return.get(ownerAlias) ); + } + + SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias ); + Type returnType = ownerPersister.getPropertyType( fetchReturn.getFetchableName() ); + + if ( returnType.isCollectionType() ) { + String role = ownerPersister.getEntityName() + '.' + fetchReturn.getFetchableName(); + Map propertyResultsMap = Collections.emptyMap();//fetchReturn.getPropertyResultsMap() + addCollection( role, alias, propertyResultsMap ); +// collectionOwnerAliases.add( ownerAlias ); + } + else if ( returnType.isEntityType() ) { + EntityType eType = ( EntityType ) returnType; + String returnEntityName = eType.getAssociatedEntityName(); + SQLLoadable persister = getSQLLoadable( returnEntityName ); + Map propertyResultsMap = Collections.emptyMap();//fetchReturn.getPropertyResultsMap() + addPersister( alias, propertyResultsMap, persister ); + } + } + + @Override + public boolean isEntityAlias(String alias) { + return this.getEntityPersister( alias ) != null; + } + + @Override + public boolean isCollectionAlias(String alias) { + return this.getCollectionPersister( alias ) != null; + } + + @Override + public SQLLoadable getEntityPersister(String alias) { + return (SQLLoadable) alias2Persister.get( alias ); + } + + @Override + public SQLLoadableCollection getCollectionPersister(String alias) { + return (SQLLoadableCollection) alias2CollectionPersister.get( alias ); + } + + @Override + public String getEntitySuffix(String alias) { + return alias2Suffix.get( alias ); + } + + @Override + public String getCollectionSuffix(String alias) { + return alias2CollectionSuffix.get( alias ); + } + + public String getOwnerAlias(String alias) { + return alias2OwnerAlias.get( alias ); + } + + @Override + public Map getPropertyResultsMap(String alias) { + return internalGetPropertyResultsMap( alias ); + } + + public String[] collectQuerySpaces() { + final HashSet spaces = new HashSet(); + collectQuerySpaces( spaces ); + return spaces.toArray( new String[ spaces.size() ] ); + } + + public void collectQuerySpaces(Collection spaces) { + for ( EntityPersister persister : alias2Persister.values() ) { + Collections.addAll( spaces, (String[]) persister.getQuerySpaces() ); + } + for ( CollectionPersister persister : alias2CollectionPersister.values() ) { + final Type elementType = persister.getElementType(); + if ( elementType.isEntityType() && ! elementType.isAnyType() ) { + final Joinable joinable = ( (EntityType) elementType ).getAssociatedJoinable( factory ); + Collections.addAll( spaces, (String[]) ( (EntityPersister) joinable ).getQuerySpaces() ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java index c799f9e038..595aed0a1b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java @@ -33,14 +33,14 @@ public class SQLQueryParser { private long aliasesFound; - interface ParserContext { + public interface ParserContext { boolean isEntityAlias(String aliasName); - SQLLoadable getEntityPersisterByAlias(String alias); - String getEntitySuffixByAlias(String alias); + SQLLoadable getEntityPersister(String alias); + String getEntitySuffix(String alias); boolean isCollectionAlias(String aliasName); - SQLLoadableCollection getCollectionPersisterByAlias(String alias); - String getCollectionSuffixByAlias(String alias); - Map getPropertyResultsMapByAlias(String alias); + SQLLoadableCollection getCollectionPersister(String alias); + String getCollectionSuffix(String alias); + Map getPropertyResultsMap(String alias); } public SQLQueryParser(String queryString, ParserContext context, SessionFactoryImplementor factory) { @@ -64,12 +64,11 @@ public class SQLQueryParser { // TODO: should "record" how many properties we have referred to - and if we // don't get them all we throw an exception! Way better than trial and error ;) protected String substituteBrackets(String sqlQuery) throws QueryException { - if ( PREPARED_STATEMENT_PATTERN.matcher( sqlQuery.trim() ).matches() ) { return sqlQuery; } - StringBuilder result = new StringBuilder( sqlQuery.length() + 20 ); + final StringBuilder result = new StringBuilder( sqlQuery.length() + 20 ); int left, right; // replace {....} with corresponding column aliases @@ -82,7 +81,7 @@ public class SQLQueryParser { } // append everything up until the next encountered open brace - result.append( sqlQuery.substring( curr, left ) ); + result.append( sqlQuery, curr, left ); if ( ( right = sqlQuery.indexOf( '}', left + 1 ) ) < 0 ) { throw new QueryException( "Unmatched braces for alias path", sqlQuery ); @@ -93,39 +92,43 @@ public class SQLQueryParser { if ( isPlaceholder ) { // Domain replacement - if ( DOMAIN_PLACEHOLDER.equals( aliasPath ) ) { - final String catalogName = factory.getSettings().getDefaultCatalogName(); - if ( catalogName != null ) { - result.append( catalogName ); - result.append( "." ); + switch ( aliasPath ) { + case DOMAIN_PLACEHOLDER: { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append( schemaName ); + result.append( "." ); + } + break; } - final String schemaName = factory.getSettings().getDefaultSchemaName(); - if ( schemaName != null ) { - result.append( schemaName ); - result.append( "." ); + // Schema replacement + case SCHEMA_PLACEHOLDER: { + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append( schemaName ); + result.append( "." ); + } + break; } - } - // Schema replacement - else if ( SCHEMA_PLACEHOLDER.equals( aliasPath ) ) { - final String schemaName = factory.getSettings().getDefaultSchemaName(); - if ( schemaName != null ) { - result.append(schemaName); - result.append("."); + // Catalog replacement + case CATALOG_PLACEHOLDER: { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + break; } - } - // Catalog replacement - else if ( CATALOG_PLACEHOLDER.equals( aliasPath ) ) { - final String catalogName = factory.getSettings().getDefaultCatalogName(); - if ( catalogName != null ) { - result.append( catalogName ); - result.append( "." ); - } - } - else { - throw new QueryException( "Unknown placeholder ", aliasPath ); + default: + throw new QueryException( "Unknown placeholder ", aliasPath ); } } - else if (context != null) { + else if ( context != null ) { int firstDot = aliasPath.indexOf( '.' ); if ( firstDot == -1 ) { if ( context.isEntityAlias( aliasPath ) ) { @@ -135,7 +138,7 @@ public class SQLQueryParser { } else { // passing through anything we do not know : to support jdbc escape sequences HB-898 - result.append( '{' ).append(aliasPath).append( '}' ); + result.append( '{' ).append( aliasPath ).append( '}' ); } } else { @@ -154,12 +157,12 @@ public class SQLQueryParser { } else { // passing through anything we do not know : to support jdbc escape sequences HB-898 - result.append( '{' ).append(aliasPath).append( '}' ); + result.append( '{' ).append( aliasPath ).append( '}' ); } } } else { - result.append( '{' ).append(aliasPath).append( '}' ); + result.append( '{' ).append( aliasPath ).append( '}' ); } } @@ -171,71 +174,71 @@ public class SQLQueryParser { private String resolveCollectionProperties( String aliasName, String propertyName) { + final Map fieldResults = context.getPropertyResultsMap( aliasName ); + final SQLLoadableCollection collectionPersister = context.getCollectionPersister( aliasName ); + final String collectionSuffix = context.getCollectionSuffix( aliasName ); - Map fieldResults = context.getPropertyResultsMapByAlias( aliasName ); - SQLLoadableCollection collectionPersister = context.getCollectionPersisterByAlias( aliasName ); - String collectionSuffix = context.getCollectionSuffixByAlias( aliasName ); + switch ( propertyName ) { + case "*": + if ( !fieldResults.isEmpty() ) { + throw new QueryException( "Using return-propertys together with * syntax is not supported." ); + } - if ( "*".equals( propertyName ) ) { - if( !fieldResults.isEmpty() ) { - throw new QueryException("Using return-propertys together with * syntax is not supported."); - } - - String selectFragment = collectionPersister.selectFragment( aliasName, collectionSuffix ); - aliasesFound++; - return selectFragment + String selectFragment = collectionPersister.selectFragment( aliasName, collectionSuffix ); + aliasesFound++; + return selectFragment + ", " + resolveProperties( aliasName, propertyName ); - } - else if ( "element.*".equals( propertyName ) ) { - return resolveProperties( aliasName, "*" ); - } - else { - String[] columnAliases; + case "element.*": + return resolveProperties( aliasName, "*" ); + default: { + String[] columnAliases; - // Let return-properties override whatever the persister has for aliases. - columnAliases = ( String[] ) fieldResults.get(propertyName); - if ( columnAliases==null ) { - columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix ); - } + // Let return-properties override whatever the persister has for aliases. + columnAliases = fieldResults.get( propertyName ); + if ( columnAliases == null ) { + columnAliases = collectionPersister.getCollectionPropertyColumnAliases( + propertyName, + collectionSuffix + ); + } - if ( columnAliases == null || columnAliases.length == 0 ) { - throw new QueryException( - "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", - originalQueryString - ); + if ( columnAliases == null || columnAliases.length == 0 ) { + throw new QueryException( + "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", + originalQueryString + ); + } + if ( columnAliases.length != 1 ) { + // TODO: better error message since we actually support composites if names are explicitly listed. + throw new QueryException( + "SQL queries only support properties mapped to a single column - property [" + + propertyName + "] is mapped to " + columnAliases.length + " columns.", + originalQueryString + ); + } + aliasesFound++; + return columnAliases[0]; } - if ( columnAliases.length != 1 ) { - // TODO: better error message since we actually support composites if names are explicitly listed. - throw new QueryException( - "SQL queries only support properties mapped to a single column - property [" + - propertyName + "] is mapped to " + columnAliases.length + " columns.", - originalQueryString - ); - } - aliasesFound++; - return columnAliases[0]; - } } private String resolveProperties(String aliasName, String propertyName) { - Map fieldResults = context.getPropertyResultsMapByAlias( aliasName ); - SQLLoadable persister = context.getEntityPersisterByAlias( aliasName ); - String suffix = context.getEntitySuffixByAlias( aliasName ); + final Map fieldResults = context.getPropertyResultsMap( aliasName ); + final SQLLoadable persister = context.getEntityPersister( aliasName ); + final String suffix = context.getEntitySuffix( aliasName ); if ( "*".equals( propertyName ) ) { if( !fieldResults.isEmpty() ) { - throw new QueryException("Using return-propertys together with * syntax is not supported."); + throw new QueryException( "Using return-propertys together with * syntax is not supported." ); } aliasesFound++; return persister.selectFragment( aliasName, suffix ) ; } else { - String[] columnAliases; // Let return-propertiess override whatever the persister has for aliases. - columnAliases = (String[]) fieldResults.get( propertyName ); + columnAliases = fieldResults.get( propertyName ); if ( columnAliases == null ) { columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java index 51bb77c8f0..11c293d72c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java @@ -82,8 +82,7 @@ public class MatchingIdSelectionHelper { final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup(); idSelectionQuery.getFromClause().addRoot( mutatingTableGroup ); - //noinspection rawtypes - final List domainResults = new ArrayList<>(); + final List> domainResults = new ArrayList<>(); targetEntityDescriptor.getIdentifierMapping().forEachSelectable( (position, selection) -> { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java index 9c3ae7c6e5..a237e9cb53 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/AbstractCteMutationHandler.java @@ -141,7 +141,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler // Create the main query spec that will return the count of final QuerySpec querySpec = new QuerySpec( true, 1 ); - final List domainResults = new ArrayList<>( 1 ); + final List> domainResults = new ArrayList<>( 1 ); final SelectStatement statement = new SelectStatement( querySpec, domainResults ); final JdbcServices jdbcServices = factory.getJdbcServices(); final SqlAstTranslator translator = jdbcServices.getJdbcEnvironment() diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/TableBasedDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/TableBasedDeleteHandler.java index eb6d3da59f..e74bdd4c51 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/TableBasedDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/TableBasedDeleteHandler.java @@ -77,11 +77,6 @@ public class TableBasedDeleteHandler } private ExecutionDelegate resolveDelegate(ExecutionContext executionContext) { - if ( ( getSqmDeleteOrUpdateStatement().getWhereClause() == null || getSqmDeleteOrUpdateStatement().getWhereClause().getPredicate() == null ) - && ! getEntityDescriptor().isAffectedByEnabledFilters( executionContext.getLoadQueryInfluencers() ) ) { - return new UnrestrictedDeleteExecutionDelegate( getEntityDescriptor() ); - } - return new RestrictedDeleteExecutionDelegate( getEntityDescriptor(), idTable, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UnrestrictedDeleteExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UnrestrictedDeleteExecutionDelegate.java deleted file mode 100644 index 70952201a7..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/idtable/UnrestrictedDeleteExecutionDelegate.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.query.sqm.mutation.internal.idtable; - -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; -import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.internal.util.MutableInteger; -import org.hibernate.internal.FilterHelper; -import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.persister.entity.Joinable; -import org.hibernate.persister.entity.JoinedSubclassEntityPersister; -import org.hibernate.query.spi.SqlOmittingQueryOptions; -import org.hibernate.query.sqm.mutation.internal.SqmMutationStrategyHelper; -import org.hibernate.sql.ast.SqlAstTranslatorFactory; -import org.hibernate.sql.ast.tree.delete.DeleteStatement; -import org.hibernate.sql.ast.tree.from.TableReference; -import org.hibernate.sql.ast.tree.predicate.Predicate; -import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl; -import org.hibernate.sql.exec.spi.ExecutionContext; -import org.hibernate.sql.exec.spi.JdbcDelete; -import org.hibernate.sql.exec.spi.JdbcParameterBindings; - -/** - * @author Steve Ebersole - */ -public class UnrestrictedDeleteExecutionDelegate implements TableBasedDeleteHandler.ExecutionDelegate { - private final EntityMappingType entityDescriptor; - - public UnrestrictedDeleteExecutionDelegate(EntityMappingType entityDescriptor) { - this.entityDescriptor = entityDescriptor; - } - - @Override - public int execute(ExecutionContext executionContext) { - // NOTE : we want the number of rows returned from this method to be the number of rows deleted - // from the root table of the entity hierarchy, which happens to be the last table we - // will visit - final MutableInteger result = new MutableInteger(); - - SqmMutationStrategyHelper.cleanUpCollectionTables( - entityDescriptor, - (tableReference, attributeMapping) -> null, - JdbcParameterBindings.NO_BINDINGS, - executionContext - ); - - entityDescriptor.visitConstraintOrderedTables( - (tableExpression, tableKeyColumnsVisitationSupplier) -> { - final int rows = deleteFrom( tableExpression, executionContext ); - result.set( rows ); - } - ); - - return result.get(); - } - - private int deleteFrom( - String tableExpression, - ExecutionContext executionContext) { - final SessionFactoryImplementor factory = executionContext.getSession().getFactory(); - - Predicate predicate = null; - if ( ! (entityDescriptor instanceof JoinedSubclassEntityPersister) || - tableExpression.equals( ( (JoinedSubclassEntityPersister) entityDescriptor ).getTableName() ) ) { - predicate = FilterHelper.createFilterPredicate( - executionContext.getLoadQueryInfluencers(), - (Joinable) entityDescriptor - ); - } - - final DeleteStatement deleteStatement = new DeleteStatement( - new TableReference( tableExpression, null, true, factory ), - predicate - ); - - final JdbcServices jdbcServices = factory.getJdbcServices(); - final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment(); - - final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( 1 ); - final SqlAstTranslatorFactory sqlAstTranslatorFactory = jdbcEnvironment.getSqlAstTranslatorFactory(); - final JdbcDelete jdbcDelete = sqlAstTranslatorFactory.buildDeleteTranslator( factory, deleteStatement ) - .translate( jdbcParameterBindings, executionContext.getQueryOptions() ); - - return jdbcServices.getJdbcMutationExecutor().execute( - jdbcDelete, - jdbcParameterBindings, - sql -> executionContext.getSession() - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( sql ), - (integer, preparedStatement) -> {}, - SqlOmittingQueryOptions.omitSqlQueryOptions( executionContext ) - ); - - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 6739391b01..1717b53891 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -210,6 +210,7 @@ import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.SqlAstJoinType; import org.hibernate.sql.ast.SqlTreeCreationException; import org.hibernate.sql.ast.SqlTreeCreationLogger; +import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.spi.FromClauseAccess; import org.hibernate.sql.ast.spi.SqlAliasBase; import org.hibernate.sql.ast.spi.SqlAliasBaseGenerator; @@ -333,7 +334,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base private final QueryParameterBindings domainParameterBindings; private final Map sqmParameterMappingModelTypes = new LinkedHashMap<>(); private final Map, Supplier>> jpaCriteriaParamResolutions; - private final List domainResults; + private final List> domainResults; private final EntityGraphTraversalState entityGraphTraversalState; private int fetchDepth; @@ -589,7 +590,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base rootPath, sqmStatement.getRoot().getAlias(), LockMode.WRITE, - () -> predicate -> additionalRestrictions = predicate, + () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, predicate ), this, getCreationContext() ); @@ -615,7 +616,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( getLoadQueryInfluencers(), - (Joinable) entityDescriptor + (Joinable) entityDescriptor, + rootTableGroup, + // todo (6.0): this is temporary until we implement proper alias support + AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.UPDATE ) ); if ( filterPredicate != null ) { additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, filterPredicate ); @@ -844,7 +848,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base rootPath, statement.getRoot().getAlias(), LockMode.WRITE, - () -> predicate -> additionalRestrictions = predicate, + () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, predicate ), this, getCreationContext() ); @@ -856,7 +860,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( getLoadQueryInfluencers(), - (Joinable) entityDescriptor + (Joinable) entityDescriptor, + rootTableGroup, + // todo (6.0): this is temporary until we implement proper alias support + AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.DELETE ) ); if ( filterPredicate != null ) { additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, filterPredicate ); @@ -924,7 +931,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base rootPath, sqmStatement.getTarget().getExplicitAlias(), LockMode.WRITE, - () -> predicate -> additionalRestrictions = predicate, + () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, predicate ), this, getCreationContext() ); @@ -1023,7 +1030,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base rootPath, sqmStatement.getTarget().getExplicitAlias(), LockMode.WRITE, - () -> predicate -> additionalRestrictions = predicate, + () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, predicate ), this, getCreationContext() ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 4ce242b2d7..2da3c7c1d7 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -2657,13 +2657,9 @@ public abstract class AbstractSqlAstTranslator implemen protected void renderTableReference(TableReference tableReference) { appendSql( tableReference.getTableExpression() ); registerAffectedTable( tableReference ); - // todo (6.0) : For now we just skip the alias rendering in the delete and update clauses - // We need some dialect support if we want to support joins in delete and update statements final Clause currentClause = clauseStack.getCurrent(); - switch ( currentClause ) { - case DELETE: - case UPDATE: - return; + if ( !rendersTableReferenceAlias( currentClause ) ) { + return; } final String identificationVariable = tableReference.getIdentificationVariable(); if ( identificationVariable != null ) { @@ -2672,6 +2668,17 @@ public abstract class AbstractSqlAstTranslator implemen } } + public static boolean rendersTableReferenceAlias(Clause clause) { + // todo (6.0) : For now we just skip the alias rendering in the delete and update clauses + // We need some dialect support if we want to support joins in delete and update statements + switch ( clause ) { + case DELETE: + case UPDATE: + return false; + } + return true; + } + protected void registerAffectedTable(TableReference tableReference) { registerAffectedTable( tableReference.getTableExpression() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseConstant.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseConstant.java new file mode 100644 index 0000000000..30491a5b59 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlAliasBaseConstant.java @@ -0,0 +1,35 @@ +/* + * 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 SqlAliasBase that always returns the same constant. + * + * @author Christian Beikov + */ +public class SqlAliasBaseConstant implements SqlAliasBase { + private final String constant; + + public SqlAliasBaseConstant(String constant) { + this.constant = constant; + } + + @Override + public String getAliasStem() { + return constant; + } + + @Override + public String generateNewAlias() { + return constant; + } + + @Override + public String toString() { + return "SqlAliasBase(" + constant + ")"; + } +} 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 index 19f9516b6e..7dbdf3ab5c 100644 --- 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 @@ -21,13 +21,13 @@ import org.hibernate.sql.results.graph.DomainResult; */ public class SelectStatement extends AbstractStatement { private final QueryPart queryPart; - private final List domainResults; + private final List> domainResults; public SelectStatement(QueryPart queryPart) { this( queryPart, Collections.emptyList() ); } - public SelectStatement(QueryPart queryPart, List domainResults) { + public SelectStatement(QueryPart queryPart, List> domainResults) { this( false, new LinkedHashMap<>(), queryPart, domainResults ); } @@ -35,7 +35,7 @@ public class SelectStatement extends AbstractStatement { boolean withRecursive, Map cteStatements, QueryPart queryPart, - List domainResults) { + List> domainResults) { super( cteStatements ); this.queryPart = queryPart; this.domainResults = domainResults; @@ -50,7 +50,7 @@ public class SelectStatement extends AbstractStatement { return queryPart; } - public List getDomainResultDescriptors() { + public List> getDomainResultDescriptors() { return domainResults; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultGraphPrinter.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultGraphPrinter.java index 785ddd03a6..94e21de419 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultGraphPrinter.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/DomainResultGraphPrinter.java @@ -26,11 +26,11 @@ public class DomainResultGraphPrinter { private static final boolean DEBUG_ENABLED = log.isDebugEnabled(); private static final boolean TRACE_ENABLED = log.isTraceEnabled(); - public static void logDomainResultGraph(List domainResults) { + public static void logDomainResultGraph(List> domainResults) { logDomainResultGraph( "DomainResult Graph", domainResults ); } - public static void logDomainResultGraph(String header, List domainResults) { + public static void logDomainResultGraph(String header, List> domainResults) { if ( ! DEBUG_ENABLED ) { return; } @@ -46,7 +46,7 @@ public class DomainResultGraphPrinter { buffer = new StringBuilder( header + ":" + System.lineSeparator() ); } - private void visitDomainResults(List domainResults) { + private void visitDomainResults(List> domainResults) { for ( int i = 0; i < domainResults.size(); i++ ) { final DomainResult domainResult = domainResults.get( i ); // DomainResults should always be the base for a branch diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java index 8c9f573de3..88c87aec90 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java @@ -43,8 +43,7 @@ public class ResultsHelper { final Map initializerMap = new LinkedHashMap<>(); final List initializers = new ArrayList<>(); - //noinspection rawtypes - final List assemblers = jdbcValues.getValuesMapping().resolveAssemblers( + final List> assemblers = jdbcValues.getValuesMapping().resolveAssemblers( new AssemblerCreationState() { @Override @@ -83,8 +82,9 @@ public class ResultsHelper { } ); + //noinspection rawtypes return new StandardRowReader<>( - assemblers, + (List) assemblers, initializers, rowTransformer, callback diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesMappingProducerStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesMappingProducerStandard.java index acfdbbf9fd..e233dcbfcb 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesMappingProducerStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesMappingProducerStandard.java @@ -29,7 +29,7 @@ public class JdbcValuesMappingProducerStandard implements JdbcValuesMappingProdu private final JdbcValuesMapping resolvedMapping; - public JdbcValuesMappingProducerStandard(List sqlSelections, List domainResults) { + public JdbcValuesMappingProducerStandard(List sqlSelections, List> domainResults) { resolvedMapping = new StandardJdbcValuesMapping( sqlSelections, domainResults ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesResultSetImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesResultSetImpl.java index 5d630b3515..c6405beef7 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesResultSetImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/JdbcValuesResultSetImpl.java @@ -49,7 +49,7 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues { this.executionContext = executionContext; this.sqlSelections = valuesMapping.getSqlSelections().toArray( new SqlSelection[0] ); - this.currentRowJdbcValues = new Object[ sqlSelections.length ]; + this.currentRowJdbcValues = new Object[ valuesMapping.getRowSize() ]; } private static QueryCachePutManager resolveQueryCachePutManager( diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/StandardJdbcValuesMapping.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/StandardJdbcValuesMapping.java index 7a0bc2d68a..cb90f37bc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/StandardJdbcValuesMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/StandardJdbcValuesMapping.java @@ -20,11 +20,11 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping; */ public class StandardJdbcValuesMapping implements JdbcValuesMapping { private final List sqlSelections; - private final List domainResults; + private final List> domainResults; public StandardJdbcValuesMapping( List sqlSelections, - List domainResults) { + List> domainResults) { this.sqlSelections = sqlSelections; this.domainResults = domainResults; } @@ -35,17 +35,22 @@ public class StandardJdbcValuesMapping implements JdbcValuesMapping { } @Override - public List getDomainResults() { + public List> getDomainResults() { return domainResults; } @Override - public List resolveAssemblers(AssemblerCreationState creationState) { - final List assemblers = CollectionHelper.arrayList( domainResults.size() ); + public int getRowSize() { + return sqlSelections.size(); + } + + @Override + public List> resolveAssemblers(AssemblerCreationState creationState) { + final List> assemblers = CollectionHelper.arrayList( domainResults.size() ); //noinspection ForLoopReplaceableByForEach for ( int i = 0; i < domainResults.size(); i++ ) { - final DomainResultAssembler resultAssembler = domainResults.get( i ).createResultAssembler( creationState ); + final DomainResultAssembler resultAssembler = domainResults.get( i ).createResultAssembler( creationState ); assemblers.add( resultAssembler ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/spi/JdbcValuesMapping.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/spi/JdbcValuesMapping.java index c86f72fc3a..42a41d2a07 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/spi/JdbcValuesMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/spi/JdbcValuesMapping.java @@ -29,7 +29,9 @@ public interface JdbcValuesMapping { */ List getSqlSelections(); - List getDomainResults(); + int getRowSize(); - List resolveAssemblers(AssemblerCreationState creationState); + List> getDomainResults(); + + List> resolveAssemblers(AssemblerCreationState creationState); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java index 6f3fdfa9ba..06295e902f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java @@ -51,7 +51,7 @@ public class FunctionTests { entity.setId(123); entity.setTheDate( new Date( 74, 2, 25 ) ); entity.setTheTime( new Time( 23, 10, 8 ) ); - entity.setTheTimestamp( new Timestamp( System.currentTimeMillis() ) ); + entity.setTheTimestamp( new Timestamp( 121, 4, 27, 13, 22, 50, 123456789 ) ); em.persist(entity); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java index 7d7a16b87a..b1af4f513e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/StandardFunctionTests.java @@ -48,7 +48,7 @@ public class StandardFunctionTests { entity.setId(123); entity.setTheDate( new Date( 74, 2, 25 ) ); entity.setTheTime( new Time( 23, 10, 8 ) ); - entity.setTheTimestamp( new Timestamp( System.currentTimeMillis() ) ); + entity.setTheTimestamp( new Timestamp( 121, 4, 27, 13, 22, 50, 123456789 ) ); em.persist(entity); } ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.java index d076a4d3ba..df7fa50e4f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeJoinWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.HashSet; import java.util.Set; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java index 0791c761f6..effdd9e140 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerManyToOneFetchModeSelectWhereTest.java @@ -4,9 +4,10 @@ * 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.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.HashSet; +import java.util.Map; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.ElementCollection; @@ -24,6 +25,7 @@ import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.Where; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; @@ -40,6 +42,10 @@ import static org.junit.Assert.assertSame; */ public class EagerManyToOneFetchModeSelectWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected void addSettings(Map settings) { + settings.put( AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLED, true ); + } @Override protected Class[] getAnnotatedClasses() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.java index e03a34c6dd..b411cf15f5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereDontUseClassWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereTest.java index 9417345891..088846a096 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereUseClassWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereUseClassWhereTest.java index f7d4462b64..870769c45a 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/EagerToManyWhereUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/EagerToManyWhereUseClassWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.java index 7fb93b2556..6ac3938fe3 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionBasicNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.ArrayList; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java index 7cd6933406..72b4a16562 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.ArrayList; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.java index fc22c47ec8..171e3cf491 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyManyToManyNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.ArrayList; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.java index 0235c12018..3f54aee298 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyOneToManyNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.ArrayList; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.java index 3856ad0710..b3bcf5eaa9 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereDontUseClassWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereTest.java index e2ceeddf20..d79dc2a350 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereUseClassWhereTest.java similarity index 99% rename from hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereUseClassWhereTest.java index 2e12f923b4..8e3fd34d2d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/annotations/LazyToManyWhereUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/annotations/LazyToManyWhereUseClassWhereTest.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 . */ -package org.hibernate.test.where.annotations; +package org.hibernate.orm.test.where.annotations; import java.util.Arrays; import java.util.HashSet; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/Category.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Category.java similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/Category.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Category.java index ce08839981..311389a047 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/Category.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Category.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; public class Category { private int id; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml index 7cd816215c..6b11b2443c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.java similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.java index ef96d0cc5b..d829b2bdc4 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeJoinWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.HashSet; import java.util.Set; @@ -25,6 +25,12 @@ import static org.junit.Assert.assertSame; */ public class EagerManyToOneFetchModeJoinWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override protected String[] getMappings() { return new String[] { "where/hbm/EagerManyToOneFetchModeJoinWhereTest.hbm.xml" }; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml similarity index 94% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml index 662d16697d..428f108b2c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java similarity index 92% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java index 12b165b5ff..7a0e923450 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerManyToOneFetchModeSelectWhereTest.java @@ -4,11 +4,14 @@ * 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.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.HashSet; +import java.util.Map; import java.util.Set; +import org.hibernate.cfg.AvailableSettings; + import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.junit.Test; @@ -24,6 +27,17 @@ import static org.junit.Assert.assertSame; */ public class EagerManyToOneFetchModeSelectWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected void addSettings(Map settings) { + settings.put( AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLED, true ); + } + + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override protected String[] getMappings() { return new String[] { "where/hbm/EagerManyToOneFetchModeSelectWhereTest.hbm.xml" }; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhere.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhere.hbm.xml similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhere.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhere.hbm.xml index 2e2455d078..7564572c45 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhere.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhere.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.java index af9db17de6..cc072ee47d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereDontUseClassWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -30,6 +30,11 @@ import static org.junit.Assert.assertTrue; */ public class EagerToManyWhereDontUseClassWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/EagerToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereTest.java index a2a9884747..b95bd50e1c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -28,6 +28,11 @@ import static org.junit.Assert.assertTrue; */ public class EagerToManyWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/EagerToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereUseClassWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereUseClassWhereTest.java index 29001f05ab..a87254231a 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/EagerToManyWhereUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/EagerToManyWhereUseClassWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -30,6 +30,11 @@ import static org.junit.Assert.assertTrue; */ public class EagerToManyWhereUseClassWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/EagerToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.hbm.xml old mode 100755 new mode 100644 similarity index 93% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.hbm.xml index 1ea7cf6b7b..37bbc60d04 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.hbm.xml @@ -12,7 +12,7 @@ - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.java old mode 100755 new mode 100644 similarity index 96% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.java index 6146cd6b44..b37bc2a324 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/File.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/File.java @@ -6,7 +6,7 @@ */ //$Id: File.java 8043 2005-08-30 15:20:42Z oneovthafew $ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Set; public class File { diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml index de297ca21b..70daec0e8d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.java index 42c01d0d19..ee678de435 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.ArrayList; import java.util.HashSet; @@ -31,6 +31,11 @@ import static org.junit.Assert.assertTrue; @RequiresDialect(H2Dialect.class) public class LazyElementCollectionBasicNonUniqueIdWhereTest extends BaseCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyElementCollectionBasicNonUniqueIdWhereTest.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml index ae850a55cb..c1b4d967b8 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java index 48aa82f82e..9e6d4c4db2 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.ArrayList; import java.util.HashSet; @@ -31,6 +31,11 @@ import static org.junit.Assert.assertTrue; @RequiresDialect(H2Dialect.class) public class LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest extends BaseCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml index ef83684956..c921dc93a9 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.java index 0310ceb1cf..f4f69c4d03 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.HashSet; import java.util.Set; @@ -26,6 +26,12 @@ import static org.junit.Assert.assertTrue; */ public class LazyManyToManyNonUniqueIdNotFoundWhereTest extends BaseCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyManyToManyNonUniqueIdNotFoundWhereTest.hbm.xml" }; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml index d0b365853c..b1637f96e5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.java index 963786330e..e7c78df7ce 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyManyToManyNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.ArrayList; import java.util.HashSet; @@ -33,6 +33,12 @@ import static org.junit.Assert.fail; */ public class LazyManyToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyManyToManyNonUniqueIdWhereTest.hbm.xml" }; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml index caf4613069..55dbd361e7 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.java similarity index 98% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.java index a6647ca5ee..5b8eab98dd 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyOneToManyNonUniqueIdWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.ArrayList; import java.util.HashSet; @@ -33,6 +33,12 @@ import static org.junit.Assert.fail; */ public class LazyOneToManyNonUniqueIdWhereTest extends BaseCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyOneToManyNonUniqueIdWhereTest.hbm.xml" }; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhere.hbm.xml b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhere.hbm.xml similarity index 95% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhere.hbm.xml rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhere.hbm.xml index a76c02c34c..1d9c198824 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhere.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhere.hbm.xml @@ -4,7 +4,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.java index 570308a7ae..88e35931a6 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereDontUseClassWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -30,6 +30,11 @@ import static org.junit.Assert.assertTrue; */ public class LazyToManyWhereDontUseClassWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereTest.java index f85ce62290..a68b3c3f86 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -28,6 +28,11 @@ import static org.junit.Assert.assertTrue; */ public class LazyToManyWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereUseClassWhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereUseClassWhereTest.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereUseClassWhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereUseClassWhereTest.java index dc02774160..990da2ae77 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/LazyToManyWhereUseClassWhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/LazyToManyWhereUseClassWhereTest.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.Arrays; import java.util.HashSet; @@ -30,6 +30,11 @@ import static org.junit.Assert.assertTrue; */ public class LazyToManyWhereUseClassWhereTest extends BaseNonConfigCoreFunctionalTestCase { + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + @Override protected String[] getMappings() { return new String[] { "where/hbm/LazyToManyWhere.hbm.xml" }; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/Product.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Product.java similarity index 97% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/Product.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Product.java index dc87c568e8..7b4ce44b76 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/Product.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/Product.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 . */ -package org.hibernate.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.HashSet; import java.util.Set; diff --git a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/WhereTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/WhereTest.java old mode 100755 new mode 100644 similarity index 87% rename from hibernate-core/src/test/java/org/hibernate/test/where/hbm/WhereTest.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/WhereTest.java index 071f983a9c..d264deda7a --- a/hibernate-core/src/test/java/org/hibernate/test/where/hbm/WhereTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/where/hbm/WhereTest.java @@ -4,14 +4,13 @@ * 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.test.where.hbm; +package org.hibernate.orm.test.where.hbm; import java.util.HashSet; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Root; @@ -30,6 +29,13 @@ import static org.junit.Assert.assertNull; * @author Max Rydahl Andersen */ public class WhereTest extends BaseCoreFunctionalTestCase { + + @Override + protected String getBaseForMappings() { + return "org/hibernate/orm/test/"; + } + + @Override public String[] getMappings() { return new String[] { "where/hbm/File.hbm.xml" }; } @@ -59,8 +65,8 @@ public class WhereTest extends BaseCoreFunctionalTestCase { public void removeTestData() { inTransaction( s -> { - s.createQuery( "update File f set f.parent = null" ).executeUpdate(); - s.createQuery( "delete File f" ).executeUpdate(); + s.createNativeQuery( "update T_FILE set parent = null" ).executeUpdate(); + s.createNativeQuery( "delete from T_FILE" ).executeUpdate(); } ); } @@ -104,11 +110,6 @@ public class WhereTest extends BaseCoreFunctionalTestCase { criteria.where( criteriaBuilder.isNull( root.get("parent") )); File parent = s.createQuery( criteria ).uniqueResult(); assertEquals( parent.getChildren().size(), 1 ); - -// File parent = (File) s.createCriteria( File.class ) -// .setFetchMode( "children", FetchMode.JOIN ) -// .add( Restrictions.isNull( "parent" ) ) -// .uniqueResult(); assertEquals( 1, parent.getChildren().size() ); } ); @@ -123,7 +124,7 @@ public class WhereTest extends BaseCoreFunctionalTestCase { .addEntity( "f", File.class ); query.addFetch( "c", "f", "children" ); - File parent = (File) ( (Object[]) query.list().get( 0 ) )[0]; + File parent = (File) query.list().get( 0 ); // @Where should not be applied assertEquals( 2, parent.getChildren().size() ); }