Move where package to orm.test and further improve result set mapping support
This commit is contained in:
parent
8936034d29
commit
fef3e53132
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
@ -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<DomainResult> domainResults = new ArrayList<>();
|
||||
final List<DomainResult<?>> domainResults = new ArrayList<>();
|
||||
|
||||
final SqlExpressionResolver sqlExpressionResolver = state.getSqlExpressionResolver();
|
||||
|
||||
|
|
|
@ -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<? extends ModelPart> partsToSelect,
|
||||
ModelPart restrictedPart,
|
||||
DomainResult<?> cachedDomainResult,
|
||||
int numberOfKeysToLoad,
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
LockOptions lockOptions,
|
||||
Consumer<JdbcParameter> 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<? extends ModelPart> partsToSelect,
|
||||
ModelPart restrictedPart,
|
||||
DomainResult<?> cachedDomainResult,
|
||||
int numberOfKeysToLoad,
|
||||
LoadQueryInfluencers loadQueryInfluencers,
|
||||
LockOptions lockOptions,
|
||||
Consumer<JdbcParameter> 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<? extends ModelPart> 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() );
|
||||
|
|
|
@ -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<String, Filter> enabledFilters,
|
||||
Set<String> treatAsDeclarations) {
|
||||
StringBuilder sessionFilterFragment = new StringBuilder();
|
||||
filterHelper.render( sessionFilterFragment, getFilterAliasGenerator( tableGroup ), enabledFilters );
|
||||
|
||||
TableReference tableReference = null;
|
||||
Set<String> 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
|
||||
|
|
|
@ -4208,10 +4208,24 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
|
||||
@Override
|
||||
public String filterFragment(TableGroup tableGroup, Map<String, Filter> enabledFilters, Set<String> treatAsDeclarations) {
|
||||
public String filterFragment(
|
||||
TableGroup tableGroup,
|
||||
Map<String, Filter> enabledFilters,
|
||||
Set<String> 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) {
|
||||
|
|
|
@ -85,16 +85,16 @@ public interface Joinable {
|
|||
return filterFragment( alias, enabledFilters, Collections.emptySet() );
|
||||
}
|
||||
|
||||
public default String filterFragment(TableGroup tableGroup, Map<String, Filter> 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<String, Filter> enabledFilters, Set<String> treatAsDeclarations) throws MappingException;
|
||||
|
||||
public String filterFragment(TableGroup tableGroup, Map<String, Filter> enabledFilters, Set<String> treatAsDeclarations) throws MappingException;
|
||||
public String filterFragment(
|
||||
TableGroup tableGroup,
|
||||
Map<String, Filter> enabledFilters,
|
||||
Set<String> treatAsDeclarations,
|
||||
boolean useIdentificationVariable) throws MappingException;
|
||||
|
||||
public String oneToManyFilterFragment(String alias) throws MappingException;
|
||||
|
||||
|
|
|
@ -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<T> extends Query<T>, 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<T> extends Query<T>, 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<T> extends Query<T>, SynchronizeableQuery {
|
|||
* from result sets.
|
||||
*/
|
||||
interface FetchReturn extends ResultNode {
|
||||
|
||||
String getTableAlias();
|
||||
|
||||
String getOwnerAlias();
|
||||
|
||||
String getFetchableName();
|
||||
|
||||
/**
|
||||
* Set the lock mode for this return.
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<SqlSelection> sqlSelections;
|
||||
private final List<DomainResult<?>> domainResults;
|
||||
public class JdbcValuesMappingImpl extends StandardJdbcValuesMapping {
|
||||
|
||||
private final int rowSize;
|
||||
|
||||
public JdbcValuesMappingImpl(
|
||||
List<SqlSelection> sqlSelections,
|
||||
List<DomainResult<?>> domainResults) {
|
||||
this.sqlSelections = sqlSelections;
|
||||
this.domainResults = domainResults;
|
||||
List<DomainResult<?>> domainResults, int rowSize) {
|
||||
super( sqlSelections, domainResults );
|
||||
this.rowSize = rowSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SqlSelection> getSqlSelections() {
|
||||
return sqlSelections;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public List<DomainResult> getDomainResults() {
|
||||
return (List) domainResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public List<DomainResultAssembler> resolveAssemblers(AssemblerCreationState creationState) {
|
||||
final List<DomainResultAssembler> assemblers = new ArrayList<>( domainResults.size() );
|
||||
domainResults.forEach(
|
||||
domainResult -> assemblers.add( domainResult.createResultAssembler( creationState ) )
|
||||
);
|
||||
return assemblers;
|
||||
public int getRowSize() {
|
||||
return rowSize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Integer, ResultBuilder> resultBuilderConsumer);
|
||||
void visitLegacyFetchBuilders(Consumer<DynamicFetchBuilderLegacy> resultBuilderConsumer);
|
||||
|
||||
void addResultBuilder(ResultBuilder resultBuilder);
|
||||
void addLegacyFetchBuilder(DynamicFetchBuilderLegacy fetchBuilder);
|
||||
|
|
|
@ -66,6 +66,19 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLegacyFetchBuilders(Consumer<DynamicFetchBuilderLegacy> resultBuilderConsumer) {
|
||||
if ( legacyFetchBuilders == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( Map.Entry<String, Map<String, DynamicFetchBuilderLegacy>> 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<SqlSelection> sqlSelections = new ArrayList<>( jdbcResultsMetadata.getColumnCount() );
|
||||
final List<SqlSelection> sqlSelections = new ArrayList<>( rowSize );
|
||||
final List<DomainResult<?>> 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(
|
||||
|
|
|
@ -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<TableGroupJoin> 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<TableGroupJoin> 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<TableGroupJoin> 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,4 +72,8 @@ public abstract class AbstractFetchBuilderContainer<T extends AbstractFetchBuild
|
|||
|
||||
return fetchBuilder;
|
||||
}
|
||||
|
||||
public void addFetchBuilder(String propertyName, DynamicFetchBuilder fetchBuilder) {
|
||||
fetchBuilderMap.put( propertyName, fetchBuilder );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,19 +10,33 @@ import java.util.List;
|
|||
import java.util.function.BiFunction;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
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.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.SqlAliasBase;
|
||||
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.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
|
||||
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.jdbc.spi.JdbcValuesMetadata;
|
||||
|
||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQuery.FetchReturn {
|
||||
|
||||
|
@ -32,6 +46,7 @@ public class DynamicFetchBuilderLegacy implements DynamicFetchBuilder, NativeQue
|
|||
private final String fetchableName;
|
||||
|
||||
private final List<String> 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<String> 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<String, String, DynamicFetchBuilderLegacy> 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String, String, DynamicFetchBuilderLegacy> 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()
|
||||
|
|
|
@ -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<O,R> implements DynamicResultBui
|
|||
int resultPosition,
|
||||
BiFunction<String, String, DynamicFetchBuilderLegacy> 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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<DynamicResultBuilderEntityStandard>
|
||||
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<String> 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<String, String, DynamicFetchBuilderLegacy> 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> T buildResultOrFetch(
|
||||
Function<TableGroup, T> 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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<R> implements NativeSelectQueryPlan<R> {
|
|||
String sql,
|
||||
Set<String> affectedTableNames,
|
||||
List<QueryParameterImplementor<?>> parameterList,
|
||||
JdbcValuesMappingProducer resultSetMapping,
|
||||
ResultSetMapping resultSetMapping,
|
||||
RowTransformer<R> 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();
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<String, NativeQuery.ResultNode> alias2Return = new HashMap<>();
|
||||
private final Map<String, String> alias2OwnerAlias = new HashMap<>();
|
||||
|
||||
private final Map<String, EntityPersister> alias2Persister = new HashMap<>();
|
||||
private final Map<String, String> alias2Suffix = new HashMap<>();
|
||||
|
||||
private final Map<String, CollectionPersister> alias2CollectionPersister = new HashMap<>();
|
||||
private final Map<String, String> alias2CollectionSuffix = new HashMap<>();
|
||||
|
||||
private final Map<String, Map<String, String[]>> entityPropertyResultMaps = new HashMap<>();
|
||||
private final Map<String, Map<String, String[]>> 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<String, String[]> internalGetPropertyResultsMap(String alias) {
|
||||
Map<String, String[]> 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<String, String[]> 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<String> 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<String> 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<String> 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<String, String[]> propertyResultsMap = Collections.emptyMap();//rootReturn.getPropertyResultsMap()
|
||||
addPersister( rootReturn.getTableAlias(), propertyResultsMap, persister );
|
||||
}
|
||||
|
||||
private void addPersister(String alias, Map<String, String[]> 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<String, String[]> 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<String, String[]> filter(Map<String, String[]> propertyResults) {
|
||||
final Map<String, String[]> result = new HashMap<>( propertyResults.size() );
|
||||
final String keyPrefix = "element.";
|
||||
|
||||
for ( Map.Entry<String, String[]> 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<String, String[]> 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<String, String[]> 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<String, String[]> getPropertyResultsMap(String alias) {
|
||||
return internalGetPropertyResultsMap( alias );
|
||||
}
|
||||
|
||||
public String[] collectQuerySpaces() {
|
||||
final HashSet<String> spaces = new HashSet<String>();
|
||||
collectQuerySpaces( spaces );
|
||||
return spaces.toArray( new String[ spaces.size() ] );
|
||||
}
|
||||
|
||||
public void collectQuerySpaces(Collection<String> 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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<String, String[]> 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<String, String[]> 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<String, String[]> 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 );
|
||||
}
|
||||
|
|
|
@ -82,8 +82,7 @@ public class MatchingIdSelectionHelper {
|
|||
final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
|
||||
idSelectionQuery.getFromClause().addRoot( mutatingTableGroup );
|
||||
|
||||
//noinspection rawtypes
|
||||
final List<DomainResult> domainResults = new ArrayList<>();
|
||||
final List<DomainResult<?>> domainResults = new ArrayList<>();
|
||||
|
||||
targetEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||
(position, selection) -> {
|
||||
|
|
|
@ -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<DomainResult> domainResults = new ArrayList<>( 1 );
|
||||
final List<DomainResult<?>> domainResults = new ArrayList<>( 1 );
|
||||
final SelectStatement statement = new SelectStatement( querySpec, domainResults );
|
||||
final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
final SqlAstTranslator<JdbcSelect> translator = jdbcServices.getJdbcEnvironment()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 )
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -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<T extends Statement> extends Base
|
|||
private final QueryParameterBindings domainParameterBindings;
|
||||
private final Map<SqmParameter,MappingModelExpressable> sqmParameterMappingModelTypes = new LinkedHashMap<>();
|
||||
private final Map<JpaCriteriaParameter<?>, Supplier<SqmJpaCriteriaParameterWrapper<?>>> jpaCriteriaParamResolutions;
|
||||
private final List<DomainResult> domainResults;
|
||||
private final List<DomainResult<?>> domainResults;
|
||||
private final EntityGraphTraversalState entityGraphTraversalState;
|
||||
|
||||
private int fetchDepth;
|
||||
|
@ -589,7 +590,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> extends Base
|
|||
rootPath,
|
||||
sqmStatement.getTarget().getExplicitAlias(),
|
||||
LockMode.WRITE,
|
||||
() -> predicate -> additionalRestrictions = predicate,
|
||||
() -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, predicate ),
|
||||
this,
|
||||
getCreationContext()
|
||||
);
|
||||
|
|
|
@ -2657,13 +2657,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> 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<T extends JdbcOperation> 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() );
|
||||
}
|
||||
|
|
|
@ -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 + ")";
|
||||
}
|
||||
}
|
|
@ -21,13 +21,13 @@ import org.hibernate.sql.results.graph.DomainResult;
|
|||
*/
|
||||
public class SelectStatement extends AbstractStatement {
|
||||
private final QueryPart queryPart;
|
||||
private final List<DomainResult> domainResults;
|
||||
private final List<DomainResult<?>> domainResults;
|
||||
|
||||
public SelectStatement(QueryPart queryPart) {
|
||||
this( queryPart, Collections.emptyList() );
|
||||
}
|
||||
|
||||
public SelectStatement(QueryPart queryPart, List<DomainResult> domainResults) {
|
||||
public SelectStatement(QueryPart queryPart, List<DomainResult<?>> domainResults) {
|
||||
this( false, new LinkedHashMap<>(), queryPart, domainResults );
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class SelectStatement extends AbstractStatement {
|
|||
boolean withRecursive,
|
||||
Map<String, CteStatement> cteStatements,
|
||||
QueryPart queryPart,
|
||||
List<DomainResult> domainResults) {
|
||||
List<DomainResult<?>> domainResults) {
|
||||
super( cteStatements );
|
||||
this.queryPart = queryPart;
|
||||
this.domainResults = domainResults;
|
||||
|
@ -50,7 +50,7 @@ public class SelectStatement extends AbstractStatement {
|
|||
return queryPart;
|
||||
}
|
||||
|
||||
public List<DomainResult> getDomainResultDescriptors() {
|
||||
public List<DomainResult<?>> getDomainResultDescriptors() {
|
||||
return domainResults;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<DomainResult> domainResults) {
|
||||
public static void logDomainResultGraph(List<DomainResult<?>> domainResults) {
|
||||
logDomainResultGraph( "DomainResult Graph", domainResults );
|
||||
}
|
||||
|
||||
public static void logDomainResultGraph(String header, List<DomainResult> domainResults) {
|
||||
public static void logDomainResultGraph(String header, List<DomainResult<?>> domainResults) {
|
||||
if ( ! DEBUG_ENABLED ) {
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class DomainResultGraphPrinter {
|
|||
buffer = new StringBuilder( header + ":" + System.lineSeparator() );
|
||||
}
|
||||
|
||||
private void visitDomainResults(List<DomainResult> domainResults) {
|
||||
private void visitDomainResults(List<DomainResult<?>> domainResults) {
|
||||
for ( int i = 0; i < domainResults.size(); i++ ) {
|
||||
final DomainResult<?> domainResult = domainResults.get( i );
|
||||
// DomainResults should always be the base for a branch
|
||||
|
|
|
@ -43,8 +43,7 @@ public class ResultsHelper {
|
|||
final Map<NavigablePath,Initializer> initializerMap = new LinkedHashMap<>();
|
||||
final List<Initializer> initializers = new ArrayList<>();
|
||||
|
||||
//noinspection rawtypes
|
||||
final List<DomainResultAssembler> assemblers = jdbcValues.getValuesMapping().resolveAssemblers(
|
||||
final List<DomainResultAssembler<?>> 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
|
||||
|
|
|
@ -29,7 +29,7 @@ public class JdbcValuesMappingProducerStandard implements JdbcValuesMappingProdu
|
|||
private final JdbcValuesMapping resolvedMapping;
|
||||
|
||||
|
||||
public JdbcValuesMappingProducerStandard(List<SqlSelection> sqlSelections, List<DomainResult> domainResults) {
|
||||
public JdbcValuesMappingProducerStandard(List<SqlSelection> sqlSelections, List<DomainResult<?>> domainResults) {
|
||||
resolvedMapping = new StandardJdbcValuesMapping( sqlSelections, domainResults );
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -20,11 +20,11 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping;
|
|||
*/
|
||||
public class StandardJdbcValuesMapping implements JdbcValuesMapping {
|
||||
private final List<SqlSelection> sqlSelections;
|
||||
private final List<DomainResult> domainResults;
|
||||
private final List<DomainResult<?>> domainResults;
|
||||
|
||||
public StandardJdbcValuesMapping(
|
||||
List<SqlSelection> sqlSelections,
|
||||
List<DomainResult> domainResults) {
|
||||
List<DomainResult<?>> domainResults) {
|
||||
this.sqlSelections = sqlSelections;
|
||||
this.domainResults = domainResults;
|
||||
}
|
||||
|
@ -35,17 +35,22 @@ public class StandardJdbcValuesMapping implements JdbcValuesMapping {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DomainResult> getDomainResults() {
|
||||
public List<DomainResult<?>> getDomainResults() {
|
||||
return domainResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DomainResultAssembler> resolveAssemblers(AssemblerCreationState creationState) {
|
||||
final List<DomainResultAssembler> assemblers = CollectionHelper.arrayList( domainResults.size() );
|
||||
public int getRowSize() {
|
||||
return sqlSelections.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DomainResultAssembler<?>> resolveAssemblers(AssemblerCreationState creationState) {
|
||||
final List<DomainResultAssembler<?>> 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 );
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ public interface JdbcValuesMapping {
|
|||
*/
|
||||
List<SqlSelection> getSqlSelections();
|
||||
|
||||
List<DomainResult> getDomainResults();
|
||||
int getRowSize();
|
||||
|
||||
List<DomainResultAssembler> resolveAssemblers(AssemblerCreationState creationState);
|
||||
List<DomainResult<?>> getDomainResults();
|
||||
|
||||
List<DomainResultAssembler<?>> resolveAssemblers(AssemblerCreationState creationState);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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() {
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.annotations;
|
||||
package org.hibernate.orm.test.where.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.hbm;
|
||||
package org.hibernate.orm.test.where.hbm;
|
||||
|
||||
public class Category {
|
||||
private int id;
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="EagerManyToOneFetchModeJoinWhereTest$Product" table="PRODUCT">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="EagerManyToOneFetchModeSelectWhereTest$Product" table="PRODUCT">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment" />
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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" };
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="Product" table="PRODUCT">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -12,7 +12,7 @@
|
|||
<!--
|
||||
Demonstrates use of a class-level where restriction
|
||||
-->
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm">
|
||||
|
||||
<class name="File" where="deleted=0" table="T_FILE">
|
||||
<id name="id">
|
|
@ -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 {
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="LazyElementCollectionBasicNonUniqueIdWhereTest$Material" table="MAIN_TABLE" where="CODE = 'MATERIAL'">
|
||||
<id name="id" column="ID">
|
||||
<generator class="assigned" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="LazyElementCollectionWithLazyManyToOneNonUniqueIdWhereTest$Material" table="MAIN_TABLE" where="CODE = 'MATERIAL'">
|
||||
<id name="id" column="ID">
|
||||
<generator class="assigned" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="LazyManyToManyNonUniqueIdNotFoundWhereTest$Material" table="MAIN_TABLE" where="CODE = 'MATERIAL'">
|
||||
<id name="id" column="ID">
|
||||
<generator class="assigned" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="LazyManyToManyNonUniqueIdWhereTest$Material" table="MAIN_TABLE" where="CODE = 'MATERIAL'">
|
||||
<id name="id" column="ID">
|
||||
<generator class="assigned" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="LazyOneToManyNonUniqueIdWhereTest$Material" table="MAIN_TABLE" where="CODE = 'MATERIAL'">
|
||||
<id name="id" column="ID">
|
||||
<generator class="assigned" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.where.hbm" default-access="property">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.where.hbm" default-access="property">
|
||||
<class name="Product" table="PRODUCT">
|
||||
<id name="id" column="ID">
|
||||
<generator class="increment" />
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.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" };
|
|
@ -4,7 +4,7 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.where.hbm;
|
||||
package org.hibernate.orm.test.where.hbm;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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() );
|
||||
}
|
Loading…
Reference in New Issue