mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-22 11:06:08 +00:00
re-enable tests
re-organize some tests support for `KEY(mapReference)` in SQM
This commit is contained in:
parent
a692061ae1
commit
c7c963075b
@ -9,26 +9,28 @@
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.engine.FetchStyle;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionConsumer;
|
||||
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectionConsumer;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.SqlAstJoinType;
|
||||
import org.hibernate.sql.ast.spi.FromClauseAccess;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
@ -174,6 +176,72 @@ public <T> DomainResult<T> createDomainResult(
|
||||
return fkTargetModelPart.createDomainResult( navigablePath, tableGroup, resultVariable, creationState );
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public <T> DomainResult<T> createDomainResult(
|
||||
// NavigablePath navigablePath,
|
||||
// TableGroup tableGroup,
|
||||
// String resultVariable,
|
||||
// DomainResultCreationState creationState) {
|
||||
// final TableGroup partTableGroup = creationState.getSqlAstCreationState().getFromClauseAccess().resolveTableGroup(
|
||||
// navigablePath,
|
||||
// (np) -> {
|
||||
// assert navigablePath.getParent() != null;
|
||||
// final TableGroup parentTableGroup = creationState.getSqlAstCreationState()
|
||||
// .getFromClauseAccess()
|
||||
// .getTableGroup( navigablePath.getParent() );
|
||||
// final TableGroupJoin join = createTableGroupJoin(
|
||||
// navigablePath,
|
||||
// parentTableGroup,
|
||||
// this,
|
||||
// creationState
|
||||
// );
|
||||
// return join.getJoinedGroup();
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// return entityMappingType.createDomainResult( navigablePath, partTableGroup, resultVariable, creationState );
|
||||
// }
|
||||
//
|
||||
// private TableGroupJoin createTableGroupJoin(
|
||||
// NavigablePath navigablePath,
|
||||
// TableGroup parentTableGroup,
|
||||
// EntityCollectionPart collectionPart,
|
||||
// DomainResultCreationState creationState) {
|
||||
// final ForeignKeyDescriptor foreignKeyDescriptor = getForeignKeyDescriptor();
|
||||
//
|
||||
// // create a TableGroup that contains the following tables:
|
||||
// // 1) the fk referring columns from the parentTableGroup
|
||||
// // 2) the associated entity tables
|
||||
// final TableGroup entityTableGroup = entityMappingType.createRootTableGroup(
|
||||
// navigablePath,
|
||||
// null,
|
||||
// false,
|
||||
// LockMode.READ,
|
||||
// () -> (predicate) -> {
|
||||
// },
|
||||
// creationState.getSqlAstCreationState(),
|
||||
// creationState.getSqlAstCreationState().getCreationContext()
|
||||
// );
|
||||
//
|
||||
// // todo (6.0) : do we need to make the FK table/columns available as well from this table group?
|
||||
//
|
||||
// final TableReference fkReferringTable = parentTableGroup.resolveTableReference( foreignKeyDescriptor.getKeyColumnContainingTable() );
|
||||
// final TableReference fkTargetTable = entityTableGroup.resolveTableReference( foreignKeyDescriptor.getTargetColumnContainingTable() );
|
||||
//
|
||||
// return new TableGroupJoin(
|
||||
// navigablePath,
|
||||
// SqlAstJoinType.INNER,
|
||||
// entityTableGroup,
|
||||
// foreignKeyDescriptor.generateJoinPredicate(
|
||||
// fkTargetTable,
|
||||
// fkReferringTable,
|
||||
// SqlAstJoinType.LEFT,
|
||||
// creationState.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||
// creationState.getSqlAstCreationState().getCreationContext()
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int forEachSelection(int offset, SelectionConsumer consumer) {
|
||||
return entityMappingType.forEachSelection( offset, consumer );
|
||||
|
@ -1353,7 +1353,7 @@ private static CollectionPart interpretElement(
|
||||
);
|
||||
|
||||
creationProcess.registerInitializationCallback(
|
||||
"EntityCollectionPart( " + elementDescriptor.getNavigableRole() + ")#finishInitialization",
|
||||
"PluralAttributeMapping( " + elementDescriptor.getNavigableRole() + ") - index descriptor",
|
||||
() -> {
|
||||
try {
|
||||
elementDescriptor.finishInitialization(
|
||||
|
@ -28,13 +28,10 @@
|
||||
import org.hibernate.mapping.List;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
|
||||
import org.hibernate.metamodel.mapping.CollectionMappingType;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMapping;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
@ -42,6 +39,8 @@
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.PropertyBasedMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.metamodel.mapping.ordering.OrderByFragment;
|
||||
import org.hibernate.metamodel.mapping.ordering.OrderByFragmentTranslator;
|
||||
|
@ -24,7 +24,7 @@ public class SelectionMappingImpl implements SelectionMapping {
|
||||
private final boolean isFormula;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
||||
private SelectionMappingImpl(
|
||||
public SelectionMappingImpl(
|
||||
String containingTableExpression,
|
||||
String selectionExpression,
|
||||
String customReadExpression,
|
||||
|
@ -32,7 +32,7 @@ public class SelectionMappingsImpl implements SelectionMappings {
|
||||
|
||||
private final SelectionMapping[] selectionMappings;
|
||||
|
||||
private SelectionMappingsImpl(SelectionMapping[] selectionMappings) {
|
||||
public SelectionMappingsImpl(SelectionMapping[] selectionMappings) {
|
||||
this.selectionMappings = selectionMappings;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionConsumer;
|
||||
import org.hibernate.metamodel.mapping.SelectionMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectionMappings;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SingleSelectionMappings implements SelectionMapping, SelectionMappings {
|
||||
private final String tableName;
|
||||
private final String expression;
|
||||
private final String readExpression;
|
||||
private final String writeExpression;
|
||||
private final boolean isFormula;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
||||
public SingleSelectionMappings(
|
||||
String tableName,
|
||||
String expression,
|
||||
String readExpression,
|
||||
String writeExpression,
|
||||
boolean isFormula,
|
||||
JdbcMapping jdbcMapping) {
|
||||
this.tableName = tableName;
|
||||
this.expression = expression;
|
||||
this.readExpression = readExpression;
|
||||
this.writeExpression = writeExpression;
|
||||
this.isFormula = isFormula;
|
||||
this.jdbcMapping = jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContainingTableExpression() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectionExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomReadExpression() {
|
||||
return readExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomWriteExpression() {
|
||||
return writeExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormula() {
|
||||
return isFormula;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionMapping getSelectionMapping(int columnIndex) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelection(int offset, SelectionConsumer consumer) {
|
||||
assert offset == 1;
|
||||
consumer.accept( offset, this );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int forEachSelection(SelectionConsumer consumer) {
|
||||
consumer.accept( 0, this );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JdbcMapping> getJdbcMappings() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.internal.MetadataContext;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
@ -53,7 +54,7 @@ protected AbstractPluralAttribute(
|
||||
this.classification = builder.getCollectionClassification();
|
||||
|
||||
this.elementPathSource = SqmMappingModelHelper.resolveSqmPathSource(
|
||||
getName(),
|
||||
CollectionPart.Nature.ELEMENT.getName(),
|
||||
builder.getValueType(),
|
||||
BindableType.PLURAL_ATTRIBUTE
|
||||
);
|
||||
|
@ -9,6 +9,7 @@
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.internal.MetadataContext;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
|
||||
import org.hibernate.metamodel.model.domain.SimpleDomainType;
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
@ -29,7 +30,7 @@ class MapAttributeImpl<X, K, V> extends AbstractPluralAttribute<X, Map<K, V>, V>
|
||||
super( xceBuilder, metadataContext );
|
||||
|
||||
this.keyPathSource = SqmMappingModelHelper.resolveSqmPathSource(
|
||||
getName(),
|
||||
CollectionPart.Nature.INDEX.getName(),
|
||||
xceBuilder.getListIndexOrMapKeyType(),
|
||||
BindableType.PLURAL_ATTRIBUTE
|
||||
);
|
||||
|
@ -94,6 +94,7 @@
|
||||
import org.hibernate.query.sqm.tree.domain.SqmCorrelation;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmIndexedCollectionAccessPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMapEntryReference;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMapJoin;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMaxElementPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMaxIndexPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMinElementPath;
|
||||
@ -4125,26 +4126,23 @@ public SqmPath<?> visitCollectionElementNavigablePath(HqlParser.CollectionElemen
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public SqmPath visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) {
|
||||
final SqmPath<?> sqmPath = consumeDomainPath( ctx.path() );
|
||||
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
|
||||
|
||||
if ( ! (referencedPathSource instanceof MapPersistentAttribute ) ) {
|
||||
throw new PathException(
|
||||
"SqmPath#referencedPathSource [" + sqmPath + "] does not refer"
|
||||
);
|
||||
if ( sqmPath instanceof SqmMapJoin ) {
|
||||
final SqmMapJoin sqmMapJoin = (SqmMapJoin) sqmPath;
|
||||
return sqmMapJoin.getReferencedPathSource().getIndexPathSource().createSqmPath( sqmMapJoin, this );
|
||||
}
|
||||
|
||||
final MapPersistentAttribute attribute = (MapPersistentAttribute) referencedPathSource;
|
||||
|
||||
//noinspection unchecked
|
||||
final SqmPath result = attribute.getKeyPathSource().createSqmPath( sqmPath, this );
|
||||
|
||||
if ( ctx.pathContinuation() != null ) {
|
||||
return consumeDomainPath( ctx.path() );
|
||||
else {
|
||||
assert sqmPath instanceof SqmPluralValuedSimplePath;
|
||||
final SqmPluralValuedSimplePath mapPath = (SqmPluralValuedSimplePath) sqmPath;
|
||||
final SqmPath keyPath = mapPath.getReferencedPathSource()
|
||||
.getIndexPathSource()
|
||||
.createSqmPath( mapPath, this );
|
||||
mapPath.registerImplicitJoinPath( keyPath );
|
||||
return keyPath;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SqmPath consumeDomainPath(HqlParser.PathContext parserPath) {
|
||||
|
@ -35,6 +35,7 @@
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.internal.FilterHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
@ -95,6 +96,7 @@
|
||||
import org.hibernate.query.sqm.sql.internal.PluralValuedSimplePathInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqlAstQueryPartProcessingStateImpl;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmMapEntryResult;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation;
|
||||
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
@ -108,6 +110,7 @@
|
||||
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMapEntryReference;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||
@ -2462,6 +2465,66 @@ public Star visitStar(SqmStar sqmStar) {
|
||||
return new Star();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object visitMapEntryFunction(SqmMapEntryReference entryRef) {
|
||||
final SqmPath mapPath = entryRef.getMapPath();
|
||||
final NavigablePath mapNavigablePath = mapPath.getNavigablePath();
|
||||
|
||||
|
||||
final TableGroup tableGroup = getFromClauseAccess().resolveTableGroup(
|
||||
mapNavigablePath,
|
||||
(navigablePath) -> {
|
||||
final TableGroup parentTableGroup = getFromClauseAccess().getTableGroup( mapNavigablePath.getParent() );
|
||||
final PluralAttributeMapping mapAttribute = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart( mapNavigablePath.getLocalName(), null );
|
||||
|
||||
final TableGroupJoin tableGroupJoin = mapAttribute.createTableGroupJoin(
|
||||
mapNavigablePath,
|
||||
parentTableGroup,
|
||||
null,
|
||||
SqlAstJoinType.INNER,
|
||||
LockMode.READ,
|
||||
sqlAliasBaseManager,
|
||||
getSqlExpressionResolver(),
|
||||
creationContext
|
||||
);
|
||||
|
||||
return tableGroupJoin.getJoinedGroup();
|
||||
}
|
||||
);
|
||||
|
||||
final PluralAttributeMapping mapDescriptor = (PluralAttributeMapping) tableGroup.getModelPart();
|
||||
|
||||
final ForeignKeyDescriptor keyDescriptor = mapDescriptor.getKeyDescriptor();
|
||||
final NavigablePath keyNavigablePath = mapNavigablePath.append( keyDescriptor.getPartName() );
|
||||
final DomainResult keyResult = keyDescriptor.createDomainResult(
|
||||
keyNavigablePath,
|
||||
tableGroup,
|
||||
this
|
||||
);
|
||||
|
||||
final CollectionPart valueDescriptor = mapDescriptor.getElementDescriptor();
|
||||
final NavigablePath valueNavigablePath = mapNavigablePath.append( valueDescriptor.getPartName() );
|
||||
final DomainResult valueResult = valueDescriptor.createDomainResult(
|
||||
valueNavigablePath,
|
||||
tableGroup,
|
||||
null,
|
||||
this
|
||||
);
|
||||
|
||||
return new DomainResultProducer() {
|
||||
@Override
|
||||
public DomainResult createDomainResult(
|
||||
String resultVariable,
|
||||
DomainResultCreationState creationState) {
|
||||
final JavaTypeDescriptor<Object> mapEntryDescriptor = getTypeConfiguration()
|
||||
.getJavaTypeDescriptorRegistry()
|
||||
.resolveDescriptor( Map.Entry.class );
|
||||
return new SqmMapEntryResult( keyResult, valueResult, resultVariable, mapEntryDescriptor );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDistinct(SqmDistinct sqmDistinct) {
|
||||
return new Distinct( (Expression) sqmDistinct.getExpression().accept( this ) );
|
||||
|
@ -12,7 +12,11 @@
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.ModelPartContainer;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.internal.EntityCollectionPart;
|
||||
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
@ -26,6 +30,9 @@
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.entity.EntityValuedFetchable;
|
||||
|
||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||
|
||||
/**
|
||||
* @author Koen Aers
|
||||
@ -78,45 +85,109 @@ private static <T> SqlTuple resolveSqlExpression(
|
||||
EntityValuedModelPart mapping) {
|
||||
final List<ColumnReference> columnReferences = new ArrayList<>();
|
||||
|
||||
assert mapping instanceof ToOneAttributeMapping;
|
||||
// todo (6.0) : "polymorphize" this
|
||||
if ( mapping instanceof ToOneAttributeMapping ) {
|
||||
final ToOneAttributeMapping toOne = (ToOneAttributeMapping) mapping;
|
||||
final ModelPart modelPart = getModelPart( sqlAstCreationState, toOne );
|
||||
|
||||
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) mapping;
|
||||
final ModelPart modelPart = getModelPart(
|
||||
sqlAstCreationState,
|
||||
toOneAttributeMapping
|
||||
);
|
||||
modelPart.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final TableReference tableReference = getTableReference(
|
||||
sqmPath,
|
||||
sqlAstCreationState,
|
||||
tableGroup,
|
||||
toOne,
|
||||
selection.getContainingTableExpression()
|
||||
);
|
||||
|
||||
modelPart.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final TableReference tableReference = getTableReference(
|
||||
sqmPath,
|
||||
sqlAstCreationState,
|
||||
tableGroup,
|
||||
toOneAttributeMapping,
|
||||
selection.getContainingTableExpression()
|
||||
);
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||
.resolveSqlExpression(
|
||||
createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
selection,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||
.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
selection,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
final EntityCollectionPart entityCollectionPart = (EntityCollectionPart) mapping;
|
||||
final NavigablePath mapNavigablePath = sqmPath.getNavigablePath().getParent();
|
||||
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
);
|
||||
final TableGroup mapTableGroup = sqlAstCreationState.getFromClauseAccess().resolveTableGroup(
|
||||
mapNavigablePath,
|
||||
(navigablePath) -> {
|
||||
final TableGroup mapParentTableGroup = sqlAstCreationState
|
||||
.getFromClauseAccess()
|
||||
.getTableGroup( mapNavigablePath.getParent() );
|
||||
|
||||
final ModelPartContainer mapParent = mapParentTableGroup.getModelPart();
|
||||
final PluralAttributeMapping mapDescriptor = (PluralAttributeMapping) mapParent.findSubPart(
|
||||
mapNavigablePath.getLocalName(),
|
||||
null
|
||||
);
|
||||
|
||||
final TableGroupJoin tableGroupJoin = mapDescriptor.createTableGroupJoin(
|
||||
navigablePath,
|
||||
mapParentTableGroup,
|
||||
null,
|
||||
SqlAstJoinType.INNER,
|
||||
LockMode.READ,
|
||||
sqlAstCreationState
|
||||
);
|
||||
|
||||
return tableGroupJoin.getJoinedGroup();
|
||||
}
|
||||
);
|
||||
|
||||
entityCollectionPart.forEachSelection(
|
||||
(selectionIndex, selectionMapping) -> {
|
||||
final TableReference tableReference = mapTableGroup.resolveTableReference( selectionMapping.getContainingTableExpression() );
|
||||
|
||||
final SqlExpressionResolver expressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
||||
|
||||
columnReferences.add(
|
||||
(ColumnReference) expressionResolver.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, selectionMapping.getSelectionExpression() ),
|
||||
(processingState) -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
selectionMapping,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
SqlTuple sqlExpression = new SqlTuple( columnReferences, mapping );
|
||||
return sqlExpression;
|
||||
}
|
||||
|
||||
private static ModelPart getModelPart(
|
||||
SqmToSqlAstConverter sqlAstCreationState,
|
||||
EntityValuedFetchable fetchable) {
|
||||
if ( fetchable instanceof ToOneAttributeMapping ) {
|
||||
final ToOneAttributeMapping toOne = (ToOneAttributeMapping) fetchable;
|
||||
final Clause current = sqlAstCreationState.getCurrentClauseStack().getCurrent();
|
||||
if ( current == Clause.SELECT ) {
|
||||
return toOne.getAssociatedEntityMappingType().getIdentifierMapping();
|
||||
}
|
||||
else {
|
||||
return toOne.getForeignKeyDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
return fetchable;
|
||||
}
|
||||
|
||||
private static ModelPart getModelPart(
|
||||
SqmToSqlAstConverter sqlAstCreationState,
|
||||
ToOneAttributeMapping toOneAttributeMapping) {
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.query.sqm.sql.internal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.JdbcValuesSourceProcessingOptions;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmMapEntryResult<K, V, R extends Map.Entry<K, V>> implements DomainResult<R> {
|
||||
private final DomainResult<K> keyResult;
|
||||
private final DomainResult<V> valueResult;
|
||||
|
||||
private final JavaTypeDescriptor<R> javaTypeDescriptor;
|
||||
private final String alias;
|
||||
|
||||
public SqmMapEntryResult(
|
||||
DomainResult<K> keyResult,
|
||||
DomainResult<V> valueResult,
|
||||
String alias,
|
||||
JavaTypeDescriptor<R> javaTypeDescriptor) {
|
||||
this.alias = alias;
|
||||
this.keyResult = keyResult;
|
||||
this.valueResult = valueResult;
|
||||
this.javaTypeDescriptor = javaTypeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultVariable() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainResultAssembler<R> createResultAssembler(AssemblerCreationState creationState) {
|
||||
final DomainResultAssembler<K> keyAssembler = keyResult.createResultAssembler( creationState );
|
||||
final DomainResultAssembler<V> valueAssembler = valueResult.createResultAssembler( creationState );
|
||||
|
||||
return new DomainResultAssembler<R>() {
|
||||
@Override
|
||||
public R assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
final K key = keyAssembler.assemble( rowProcessingState, options );
|
||||
final V value = valueAssembler.assemble( rowProcessingState, options );
|
||||
//noinspection unchecked
|
||||
return (R) new MapEntryImpl<>( key, value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<R> getAssembledJavaTypeDescriptor() {
|
||||
return javaTypeDescriptor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaTypeDescriptor<R> getResultJavaTypeDescriptor() {
|
||||
return javaTypeDescriptor;
|
||||
}
|
||||
|
||||
public static class MapEntryImpl<K,V> implements Map.Entry<K,V> {
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public MapEntryImpl(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
@ -11,16 +11,14 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
|
||||
import org.hibernate.query.criteria.JpaSelection;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SqmExpressable;
|
||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||
import org.hibernate.query.sqm.SqmExpressable;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
|
||||
@ -32,7 +30,7 @@
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SqmMapEntryReference<K,V>
|
||||
implements SqmSelectableNode<Map.Entry<K,V>>, Expression<Map.Entry<K,V>>, DomainResultProducer<Map.Entry<K,V>> {
|
||||
implements SqmSelectableNode<Map.Entry<K,V>>, Expression<Map.Entry<K,V>> {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private final SqmPath<?> mapPath;
|
||||
private final NodeBuilder nodeBuilder;
|
||||
@ -86,6 +84,7 @@ public <X> X accept(SemanticQueryWalker<X> walker) {
|
||||
|
||||
@Override
|
||||
public void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer) {
|
||||
jpaSelectionConsumer.accept( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -146,4 +145,5 @@ public Predicate in(Expression<Collection<?>> values) {
|
||||
public <X> Expression<X> as(Class<X> type) {
|
||||
throw new UnsupportedOperationException( "Whatever JPA" );
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user