HHH-14318 Introduce column mapping abstract to support formulas easily

This commit is contained in:
Christian Beikov 2020-12-10 11:56:13 +01:00
parent cb7c65e49d
commit 4de1870785
123 changed files with 2206 additions and 2153 deletions

View File

@ -11,6 +11,7 @@ import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import org.hibernate.NotYetImplementedFor6Exception;
@ -50,7 +51,7 @@ import org.hibernate.usertype.UserType;
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class TypeDefinition implements Serializable {
public static final MutableInteger NAME_COUNTER = new MutableInteger();
public static final AtomicInteger NAME_COUNTER = new AtomicInteger();
private final String name;
private final Class typeImplementorClass;

View File

@ -82,16 +82,14 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
columnByReferencedName.put( referencedColumnName.toLowerCase(Locale.ROOT), joinColumn );
}
//try default column orientation
MutableInteger index = new MutableInteger();
if ( columnByReferencedName.isEmpty() ) {
isExplicitReference = false;
for ( Ejb3JoinColumn joinColumn : joinColumns ) {
columnByReferencedName.put( String.valueOf( index.get() ), joinColumn );
index.getAndIncrement();
for ( int i = 0; i < joinColumns.length; i++ ) {
columnByReferencedName.put( String.valueOf( i ), joinColumns[i] );
}
index.set( 0 );
}
MutableInteger index = new MutableInteger();
while ( properties.hasNext() ) {
Property referencedProperty = properties.next();
if ( referencedProperty.isComposite() ) {

View File

@ -131,7 +131,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
final CompositeIdentifierMapping cidMapping = (CompositeIdentifierMapping) idMapping;
if ( cidMapping.getAttributeCount() == 1 ) {
final AttributeMapping singleIdAttribute = cidMapping.getAttributes().iterator().next();
final AttributeMapping singleIdAttribute = cidMapping.getAttributes().get( 0 );
if ( singleIdAttribute.getMappedType() instanceof EntityMappingType ) {
final EntityMappingType dependentIdTargetMapping = (EntityMappingType) singleIdAttribute.getMappedType();
final EntityIdentifierMapping dependentIdTargetIdMapping = dependentIdTargetMapping.getIdentifierMapping();

View File

@ -255,22 +255,15 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
entityDescriptor().getIdentifierMapping().visitJdbcValues(
int offset = jdbcParamBindings.registerParametersForEachJdbcValue(
id,
Clause.WHERE,
(value, type) -> {
assert jdbcParamItr.hasNext();
final JdbcParameter jdbcParam = jdbcParamItr.next();
jdbcParamBindings.addBinding(
jdbcParam,
new JdbcParameterBindingImpl( type, value )
);
},
entityDescriptor().getIdentifierMapping(),
jdbcParameters,
session
);
assert offset == jdbcParameters.size();
final List<Object[]> results = session.getFactory().getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,

View File

@ -67,13 +67,13 @@ public class CollectionElementLoaderByIndex implements Loader {
EntityIdentifierMapping identifierMapping = ( (EntityCollectionPart) indexDescriptor ).getEntityMappingType()
.getIdentifierMapping();
restrictedParts.add( identifierMapping );
this.keyJdbcCount = keyDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() ) +
identifierMapping.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
this.keyJdbcCount = keyDescriptor.getJdbcTypeCount() +
identifierMapping.getJdbcTypeCount();
}
else {
restrictedParts.add( indexDescriptor );
this.keyJdbcCount = keyDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() ) +
indexDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
this.keyJdbcCount = keyDescriptor.getJdbcTypeCount() +
indexDescriptor.getJdbcTypeCount();
}
List<ModelPart> partsToSelect = new ArrayList<>();
@ -122,35 +122,22 @@ public class CollectionElementLoaderByIndex implements Loader {
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
attributeMapping.getKeyDescriptor().visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
key,
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
attributeMapping.getKeyDescriptor(),
jdbcParameters,
session
);
attributeMapping.getIndexDescriptor().visitJdbcValues(
offset += jdbcParameterBindings.registerParametersForEachJdbcValue(
incrementIndexByBase( index ),
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
offset,
attributeMapping.getIndexDescriptor(),
jdbcParameters,
session
);
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
List<Object> list = jdbcServices.getJdbcSelectExecutor().list(
jdbcSelect,

View File

@ -61,7 +61,7 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
this.attributeMapping = attributeMapping;
this.batchSize = batchSize;
this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount();
this.batchSizeJdbcParameters = new ArrayList<>();
this.batchSizeSqlAst = LoaderSelectBuilder.createSelect(
@ -164,20 +164,15 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount * smallBatchLength );
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
int offset = 0;
for ( int i = smallBatchStart; i < smallBatchStart + smallBatchLength; i++ ) {
getLoadable().getKeyDescriptor().visitJdbcValues(
offset += jdbcParameterBindings.registerParametersForEachJdbcValue(
batchIds[i],
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
offset,
getLoadable().getKeyDescriptor(),
jdbcParameters,
session
);
@ -210,7 +205,7 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
);
}
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
// prepare for the next round...
smallBatchStart += smallBatchLength;

View File

@ -53,7 +53,7 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
SessionFactoryImplementor sessionFactory) {
this.attributeMapping = attributeMapping;
this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
this.keyJdbcCount = attributeMapping.getKeyDescriptor().getJdbcTypeCount();
this.jdbcParameters = new ArrayList<>();
this.sqlAst = LoaderSelectBuilder.createSelect(
@ -100,22 +100,14 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount );
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
attributeMapping.getKeyDescriptor().visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
key,
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
attributeMapping.getKeyDescriptor(),
jdbcParameters,
session
);
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
jdbcServices.getJdbcSelectExecutor().list(
jdbcSelect,

View File

@ -68,27 +68,22 @@ public class CompoundNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
assert naturalIdToLoad instanceof Object[];
final Object[] naturalIdValueArray = (Object[]) naturalIdToLoad;
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
int offset = 0;
for ( int i = 0; i < naturalIdMapping().getNaturalIdAttributes().size(); i++ ) {
final SingularAttributeMapping attrMapping = naturalIdMapping().getNaturalIdAttributes().get( i );
attrMapping.visitJdbcValues(
offset += jdbcParamBindings.registerParametersForEachJdbcValue(
naturalIdValueArray[i],
Clause.WHERE,
(jdbcValue, jdbcMapping) -> {
assert jdbcParamItr.hasNext();
final JdbcParameter jdbcParam = jdbcParamItr.next();
jdbcParamBindings.addBinding(
jdbcParam,
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
},
offset,
attrMapping,
jdbcParameters,
session
);
}
// make sure we've exhausted all JDBC parameters
assert ! jdbcParamItr.hasNext();
assert offset == jdbcParameters.size();
}
@Override

View File

@ -93,29 +93,25 @@ class DatabaseSnapshotExecutor {
rootQuerySpec.getFromClause().addRoot( rootTableGroup );
jdbcParameters = new ArrayList<>(
entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() )
entityDescriptor.getIdentifierMapping().getJdbcTypeCount()
);
//noinspection rawtypes
final List<DomainResult> domainResults = new ArrayList<>();
entityDescriptor.getIdentifierMapping().visitColumns(
(tab, col, isColFormula, readFragment, writeFragment, jdbcMapping) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( tab );
entityDescriptor.getIdentifierMapping().forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping );
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
jdbcParameters.add( jdbcParameter );
final ColumnReference columnReference = (ColumnReference) state.getSqlExpressionResolver()
.resolveSqlExpression(
createColumnReferenceKey( tableReference, col ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
s -> new ColumnReference(
tableReference,
col,
isColFormula,
readFragment,
writeFragment,
jdbcMapping,
selection,
sessionFactory
)
);
@ -130,7 +126,7 @@ class DatabaseSnapshotExecutor {
final SqlSelection sqlSelection = state.getSqlExpressionResolver().resolveSqlSelection(
columnReference,
jdbcMapping.getJavaTypeDescriptor(),
selection.getJdbcMapping().getJavaTypeDescriptor(),
sessionFactory.getTypeConfiguration()
);
@ -139,7 +135,7 @@ class DatabaseSnapshotExecutor {
new BasicResult<Object>(
sqlSelection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
selection.getJdbcMapping().getJavaTypeDescriptor()
)
);
}
@ -148,21 +144,17 @@ class DatabaseSnapshotExecutor {
entityDescriptor.visitStateArrayContributors(
contributorMapping -> {
rootPath.append( contributorMapping.getAttributeName() );
contributorMapping.visitColumns(
(table, column, isFormula, customReadExpr, customWriteExpr, jdbcMapping) -> {
contributorMapping.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(
table );
selection.getContainingTableExpression() );
final ColumnReference columnReference = (ColumnReference) state.getSqlExpressionResolver()
.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
s -> new ColumnReference(
tableReference,
column,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
sessionFactory
)
);
@ -170,7 +162,7 @@ class DatabaseSnapshotExecutor {
final SqlSelection sqlSelection = state.getSqlExpressionResolver()
.resolveSqlSelection(
columnReference,
jdbcMapping.getJavaTypeDescriptor(),
selection.getJdbcMapping().getJavaTypeDescriptor(),
sessionFactory.getTypeConfiguration()
);
@ -179,7 +171,7 @@ class DatabaseSnapshotExecutor {
new BasicResult<Object>(
sqlSelection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
selection.getJdbcMapping().getJavaTypeDescriptor()
)
);
}
@ -202,25 +194,17 @@ class DatabaseSnapshotExecutor {
}
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(
entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() )
entityDescriptor.getIdentifierMapping().getJdbcTypeCount()
);
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
entityDescriptor.getIdentifierMapping().visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
id,
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
entityDescriptor.getIdentifierMapping(),
jdbcParameters,
session
);
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
final List<?> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
jdbcSelect,

View File

@ -29,7 +29,6 @@ import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.loader.MultipleBagFetchException;
import org.hibernate.loader.ast.spi.Loadable;
import org.hibernate.loader.ast.spi.Loader;
@ -389,9 +388,7 @@ public class LoaderSelectBuilder {
}
for ( ModelPart restrictedPart : restrictedParts ) {
final int numberOfRestrictionColumns = restrictedPart.getJdbcTypeCount(
creationContext.getDomainModel().getTypeConfiguration()
);
final int numberOfRestrictionColumns = restrictedPart.getJdbcTypeCount();
applyRestriction(
rootQuerySpec,
@ -430,26 +427,22 @@ public class LoaderSelectBuilder {
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
if ( numberColumns == 1 ) {
modelPart.visitColumns(
(table, column, isFormula, customReadExpr, customWriteExpr, jdbcMapping) -> {
modelPart.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference(
table );
selection.getContainingTableExpression() );
final ColumnReference columnRef =
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
p -> new ColumnReference(
tableReference,
column,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
creationContext.getSessionFactory()
)
);
if ( numberOfKeysToLoad == 1 ) {
final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping );
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
jdbcParameterConsumer.accept( jdbcParameter );
rootQuerySpec.applyPredicate(
@ -474,19 +467,15 @@ public class LoaderSelectBuilder {
else {
final List<ColumnReference> columnReferences = new ArrayList<>( numberColumns );
modelPart.visitColumns(
(table, column, isFormula, customReadExpr, customWriteExpr, jdbcMapping) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( table );
modelPart.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = rootTableGroup.resolveTableReference( selection.getContainingTableExpression() );
columnReferences.add(
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
p -> new ColumnReference(
tableReference,
column,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
creationContext.getSessionFactory()
)
)
@ -838,18 +827,18 @@ public class LoaderSelectBuilder {
final Expression fkExpression;
final int jdbcTypeCount = fkDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int jdbcTypeCount = fkDescriptor.getJdbcTypeCount();
if ( jdbcTypeCount == 1 ) {
assert fkDescriptor instanceof SimpleForeignKeyDescriptor;
final SimpleForeignKeyDescriptor simpleFkDescriptor = (SimpleForeignKeyDescriptor) fkDescriptor;
fkExpression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
createColumnReferenceKey(
simpleFkDescriptor.getContainingTableExpression(),
simpleFkDescriptor.getMappedColumnExpression()
simpleFkDescriptor.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( simpleFkDescriptor.getContainingTableExpression() ),
simpleFkDescriptor.getMappedColumnExpression(),
simpleFkDescriptor.getSelectionExpression(),
false,
null,
null,
@ -860,18 +849,14 @@ public class LoaderSelectBuilder {
}
else {
final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount );
fkDescriptor.visitColumns(
(table, column, isFormula, customReadExpr, customWriteExpr, jdbcMapping) ->
fkDescriptor.forEachSelection(
(columnIndex, selection) ->
columnReferences.add(
(ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
createColumnReferenceKey( table, column ),
createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
rootTableGroup.resolveTableReference( table ),
column,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
rootTableGroup.resolveTableReference( selection.getContainingTableExpression() ),
selection,
this.creationContext.getSessionFactory()
)
)
@ -918,24 +903,18 @@ public class LoaderSelectBuilder {
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
final MutableInteger count = new MutableInteger();
fkDescriptor.visitTargetColumns(
(table, column, isFormula, customReadExpr, customWriteExpr, jdbcMapping) -> {
(valuesPosition, selection) -> {
// for each column, resolve a SqlSelection and add it to the sub-query select-clause
final TableReference tableReference = ownerTableGroup.resolveTableReference( table );
final TableReference tableReference = ownerTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final Expression expression = sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableReference,
column,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
sessionFactory
)
);
final int valuesPosition = count.getAndIncrement();
subQuery.getSelectClause().addSqlSelection(
new SqlSelectionImpl(
valuesPosition + 1,

View File

@ -81,7 +81,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
if ( idJdbcTypeCount < 0 ) {
// can't do this in the ctor because of chicken-egg between this ctor and the persisters
idJdbcTypeCount = entityDescriptor.getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
idJdbcTypeCount = entityDescriptor.getIdentifierMapping().getJdbcTypeCount();
}
if ( loadOptions.isOrderReturnEnabled() ) {
@ -258,28 +258,23 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
int offset = 0;
for ( int i = 0; i < numberOfIdsInBatch; i++ ) {
final Object id = idsInBatch.get( i );
entityDescriptor.getIdentifierMapping().visitJdbcValues(
offset += jdbcParameterBindings.registerParametersForEachJdbcValue(
id,
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
offset,
entityDescriptor.getIdentifierMapping(),
jdbcParameters,
session
);
}
// we should have used all of the JdbcParameter references (created bindings for all)
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
final LoadingEntityCollector loadingEntityCollector;

View File

@ -57,7 +57,7 @@ public class MultiNaturalIdLoaderStandard<E> implements MultiNaturalIdLoader<E>
}
else {
maxBatchSize = session.getJdbcServices().getJdbcEnvironment().getDialect().getDefaultBatchLoadSizingStrategy().determineOptimalBatchLoadSize(
entityDescriptor.getNaturalIdMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() ),
entityDescriptor.getNaturalIdMapping().getJdbcTypeCount(),
naturalIds.length
);
}

View File

@ -19,6 +19,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.loader.ast.spi.MultiNaturalIdLoadOptions;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.query.spi.QueryOptions;
@ -100,54 +101,41 @@ public class MultiNaturalIdLoadingBatcher {
public <E> List<E> multiLoad(Object[] naturalIdValues, MultiNaturalIdLoadOptions options, SharedSessionContractImplementor session) {
final ArrayList<E> multiLoadResults = CollectionHelper.arrayList( naturalIdValues.length );
final JdbcParameterBindingsImpl jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
boolean needsExecution = false;
int offset = 0;
for ( int i = 0; i < naturalIdValues.length; i++ ) {
final JdbcParameterBindings jdbcParamBindingsRef = jdbcParamBindings;
final Iterator<JdbcParameter> jdbcParamItrRef = jdbcParamItr;
final Object bindValue = keyValueResolver.resolveKeyToLoad( naturalIdValues[ i ], session );
if ( bindValue != null ) {
entityDescriptor.getNaturalIdMapping().visitJdbcValues(
offset += jdbcParamBindings.registerParametersForEachJdbcValue(
bindValue,
Clause.IRRELEVANT,
(jdbcValue, jdbcMapping) -> jdbcParamBindingsRef.addBinding(
jdbcParamItrRef.next(),
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
),
offset,
entityDescriptor.getNaturalIdMapping(),
jdbcParameters,
session
);
needsExecution = true;
}
if ( ! jdbcParamItr.hasNext() ) {
if ( offset == jdbcParameters.size() ) {
// we've hit the batch mark
final List<E> batchResults = performLoad( jdbcParamBindings, session );
multiLoadResults.addAll( batchResults );
jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
jdbcParamItr = jdbcParameters.iterator();
needsExecution = false;
jdbcParamBindings.clear();
offset = 0;
}
}
if ( needsExecution ) {
while ( jdbcParamItr.hasNext() ) {
final JdbcParameterBindings jdbcParamBindingsRef = jdbcParamBindings;
final Iterator<JdbcParameter> jdbcParamItrRef = jdbcParamItr;
if ( offset != 0 ) {
while ( offset != jdbcParameters.size() ) {
// pad the remaining parameters with null
entityDescriptor.getNaturalIdMapping().visitJdbcValues(
offset += jdbcParamBindings.registerParametersForEachJdbcValue(
null,
Clause.IRRELEVANT,
(jdbcValue, jdbcMapping) -> jdbcParamBindingsRef.addBinding(
jdbcParamItrRef.next(),
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
),
offset,
entityDescriptor.getNaturalIdMapping(),
jdbcParameters,
session
);
}

View File

@ -66,16 +66,11 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
final Object bindableValue = naturalIdMapping().normalizeValue( naturalIdToLoad, session );
final SingularAttributeMapping attributeMapping = naturalIdMapping().getNaturalIdAttributes().get( 0 );
attributeMapping.visitJdbcValues(
jdbcParamBindings.registerParametersForEachJdbcValue(
bindableValue,
Clause.WHERE,
(jdbcValue, jdbcMapping) -> {
final JdbcParameter jdbcParam = jdbcParameters.get( 0 );
jdbcParamBindings.addBinding(
jdbcParam,
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
},
attributeMapping,
jdbcParameters,
session
);
}
@ -109,19 +104,12 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
entityDescriptor().getIdentifierMapping().visitJdbcValues(
jdbcParamBindings.registerParametersForEachJdbcValue(
id,
Clause.WHERE,
(value, type) -> {
assert jdbcParamItr.hasNext();
final JdbcParameter jdbcParam = jdbcParamItr.next();
jdbcParamBindings.addBinding(
jdbcParam,
new JdbcParameterBindingImpl( type, value )
);
},
entityDescriptor().getIdentifierMapping(),
jdbcParameters,
session
);
@ -201,19 +189,13 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlSelect );
final JdbcParameterBindings jdbcParamBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
final SingularAttributeMapping attributeMapping = naturalIdMapping().getAttribute();
attributeMapping.visitJdbcValues(
jdbcParamBindings.registerParametersForEachJdbcValue(
bindValue,
Clause.WHERE,
(jdbcValue, jdbcMapping) -> {
assert jdbcParamItr.hasNext();
jdbcParamBindings.addBinding(
jdbcParamItr.next(),
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
},
attributeMapping,
jdbcParameters,
session
);

View File

@ -105,26 +105,18 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl(
getLoadable().getIdentifierMapping().getJdbcTypeCount( sessionFactory.getTypeConfiguration() )
getLoadable().getIdentifierMapping().getJdbcTypeCount()
);
for ( int i = 0; i < numberOfIds; i++ ) {
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
getLoadable().getIdentifierMapping().visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
idsToLoad[i],
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
getLoadable().getIdentifierMapping(),
jdbcParameters,
session
);
assert !paramItr.hasNext();
assert offset == jdbcParameters.size();
}
JdbcSelectExecutorStandardImpl.INSTANCE.list(

View File

@ -98,29 +98,24 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
final int jdbcTypeCount = restrictivePart.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int jdbcTypeCount = restrictivePart.getJdbcTypeCount();
assert jdbcParameters.size() % jdbcTypeCount == 0;
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount );
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
final Iterator<JdbcParameter> paramItr = jdbcParameters.iterator();
while ( paramItr.hasNext() ) {
restrictivePart.visitJdbcValues(
int offset = 0;
while ( offset < jdbcParameters.size() ) {
offset += jdbcParameterBindings.registerParametersForEachJdbcValue(
restrictedValue,
Clause.WHERE,
(value, type) -> {
assert paramItr.hasNext();
final JdbcParameter parameter = paramItr.next();
jdbcParameterBindings.addBinding(
parameter,
new JdbcParameterBindingImpl( type, value )
);
},
offset,
restrictivePart,
jdbcParameters,
session
);
}
assert offset == jdbcParameters.size();
final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
jdbcSelect,

View File

@ -89,20 +89,14 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
uniqueKeyAttribute.visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
ukValue,
Clause.WHERE,
(jdbcValue, jdbcMapping) -> {
assert jdbcParamItr.hasNext();
final JdbcParameter jdbcParameter = jdbcParamItr.next();
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
},
uniqueKeyAttribute,
jdbcParameters,
session
);
assert offset == jdbcParameters.size();
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
@ -173,20 +167,14 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
final JdbcSelect jdbcSelect = sqlAstTranslatorFactory.buildSelectTranslator( sessionFactory ).translate( sqlAst );
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcParameters.size() );
final Iterator<JdbcParameter> jdbcParamItr = jdbcParameters.iterator();
uniqueKeyAttribute.visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
ukValue,
Clause.WHERE,
(jdbcValue, jdbcMapping) -> {
assert jdbcParamItr.hasNext();
final JdbcParameter jdbcParameter = jdbcParamItr.next();
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
},
uniqueKeyAttribute,
jdbcParameters,
session
);
assert offset == jdbcParameters.size();
final List<Object> list = sessionFactory.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,

View File

@ -25,6 +25,7 @@ import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.type.ComponentType;
@ -79,7 +80,7 @@ public class Component extends SimpleValue implements MetaAttributable {
return properties.size();
}
public Iterator getPropertyIterator() {
public Iterator<Property> getPropertyIterator() {
return properties.iterator();
}
@ -106,13 +107,13 @@ public class Component extends SimpleValue implements MetaAttributable {
@Override
@SuppressWarnings("unchecked")
public Iterator<Selectable> getColumnIterator() {
Iterator[] iters = new Iterator[ getPropertySpan() ];
Iterator iter = getPropertyIterator();
int i=0;
Iterator<Selectable>[] iters = new Iterator[ getPropertySpan() ];
Iterator<Property> iter = getPropertyIterator();
int i = 0;
while ( iter.hasNext() ) {
iters[i++] = ( (Property) iter.next() ).getColumnIterator();
iters[i++] = iter.next().getColumnIterator();
}
return new JoinedIterator( iters );
return new JoinedIterator<>( iters );
}
public boolean isEmbedded() {

View File

@ -0,0 +1,18 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.mapping;
/**
* A consumer like {@link java.util.function.BiConsumer} but also accepts an integer as index.
*
* @author Christian Beikov
*/
@FunctionalInterface
public interface IndexedBiConsumer<T, U> {
void accept(int index, T t, U u);
}

View File

@ -0,0 +1,18 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.mapping;
/**
* A consumer like {@link java.util.function.Consumer} but also accepts an integer as index.
*
* @author Christian Beikov
*/
@FunctionalInterface
public interface IndexedConsumer<T> {
void accept(int index, T t);
}

View File

@ -73,7 +73,7 @@ public class Property implements Serializable, MetaAttributable {
return value.getColumnSpan();
}
public Iterator getColumnIterator() {
public Iterator<Selectable> getColumnIterator() {
return value.getColumnIterator();
}

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.metamodel.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@ -17,13 +15,15 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.SelectionMappings;
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
@ -51,7 +51,6 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Base implementation for composite identifier mappings
@ -64,9 +63,6 @@ public abstract class AbstractCompositeIdentifierMapping
private final String tableExpression;
private final StateArrayContributorMetadataAccess attributeMetadataAccess;
private final List<String> columnNames;
private final List<String> customReadExpressions;
private final List<String> customWriteExpressions;
private final EntityMappingType entityMapping;
private final EmbeddableMappingType embeddableDescriptor;
@ -78,7 +74,6 @@ public abstract class AbstractCompositeIdentifierMapping
EmbeddableMappingType embeddableDescriptor,
EntityMappingType entityMapping,
String tableExpression,
String[] columnNames,
SessionFactoryImplementor sessionFactory) {
this.attributeMetadataAccess = attributeMetadataAccess;
this.embeddableDescriptor = embeddableDescriptor;
@ -86,10 +81,6 @@ public abstract class AbstractCompositeIdentifierMapping
this.tableExpression = tableExpression;
this.sessionFactory = sessionFactory;
this.columnNames = Arrays.asList( columnNames );
this.customReadExpressions = new ArrayList<>( columnNames.length );
this.customWriteExpressions = new ArrayList<>( columnNames.length );
this.navigableRole = entityMapping.getNavigableRole()
.appendContainer( EntityIdentifierMapping.ROLE_LOCAL_NAME );
}
@ -125,33 +116,23 @@ public abstract class AbstractCompositeIdentifierMapping
}
@Override
public List<String> getMappedColumnExpressions() {
return columnNames;
}
@Override
public List<String> getCustomReadExpressions() {
return customReadExpressions;
}
@Override
public List<String> getCustomWriteExpressions() {
return customWriteExpressions;
}
@Override
public void visitColumns(ColumnConsumer consumer) {
getAttributes().forEach(
attribute -> {
public int forEachSelection(int offset, SelectionConsumer consumer) {
int span = 0;
final List<SingularAttributeMapping> attributes = getAttributes();
for ( int i = 0; i < attributes.size(); i++ ) {
final SingularAttributeMapping attribute = attributes.get( i );
if ( attribute instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping associationAttributeMapping = (ToOneAttributeMapping) attribute;
associationAttributeMapping.getForeignKeyDescriptor().visitReferringColumns( consumer );
span += associationAttributeMapping.getForeignKeyDescriptor().visitReferringColumns(
span + offset,
consumer
);
}
else {
attribute.visitColumns( consumer );
span += attribute.forEachSelection( span + offset, consumer );
}
}
);
return span;
}
@Override
@ -209,21 +190,16 @@ public abstract class AbstractCompositeIdentifierMapping
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
embeddableDescriptor.visitJdbcTypes( action, clause, typeConfiguration );
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
getEmbeddableTypeDescriptor().getAttributeMappings().forEach(
attributeMapping -> {
int span = 0;
final List<AttributeMapping> attributeMappings = getEmbeddableTypeDescriptor().getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i );
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
if ( attributeMapping instanceof ToOneAttributeMapping ) {
final EntityMappingType associatedEntityMappingType =
@ -231,13 +207,19 @@ public abstract class AbstractCompositeIdentifierMapping
final EntityIdentifierMapping identifierMapping =
associatedEntityMappingType.getIdentifierMapping();
final Object identifier = identifierMapping.getIdentifier( o, session );
identifierMapping.visitJdbcValues( identifier, clause, valuesConsumer, session );
span += identifierMapping.forEachJdbcValue(
identifier,
clause,
span + offset,
valuesConsumer,
session
);
}
else {
attributeMapping.visitJdbcValues( o, clause, valuesConsumer, session );
span += attributeMapping.forEachJdbcValue( o, clause, span + offset, valuesConsumer, session );
}
}
);
return span;
}
@Override
@ -246,39 +228,29 @@ public abstract class AbstractCompositeIdentifierMapping
Clause clause,
SqmToSqlAstConverter walker,
SqlAstCreationState sqlAstCreationState) {
final List<String> attrColumnNames = getMappedColumnExpressions();
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( attrColumnNames.size() );
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
getEmbeddableTypeDescriptor().visitJdbcTypes(
new Consumer<JdbcMapping>() {
private int index = 0;
@Override
public void accept(JdbcMapping jdbcMapping) {
final String attrColumnExpr = attrColumnNames.get( index++ );
final SelectionMappings selectionMappings = getEmbeddableTypeDescriptor();
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( selectionMappings.getJdbcTypeCount() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
getEmbeddableTypeDescriptor().forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
? defaultTableReference
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
attrColumnExpr
selection.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
attrColumnExpr,
false,
null,
null,
jdbcMapping,
selection,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
);
columnReferences.add( (ColumnReference) columnReference );
}
},
clause,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
return new SqlTuple( columnReferences, this );
@ -326,4 +298,5 @@ public abstract class AbstractCompositeIdentifierMapping
protected EntityMappingType getEntityMapping() {
return entityMapping;
}
}

View File

@ -9,9 +9,6 @@ package org.hibernate.metamodel.mapping;
import java.util.Collections;
import java.util.List;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Any basic-typed ValueMapping - e.g. a basic-valued singular attribute or a
* basic-valued collection element
@ -25,12 +22,12 @@ import org.hibernate.type.spi.TypeConfiguration;
*/
public interface BasicValuedMapping extends ValueMapping, SqlExpressable {
@Override
default int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
default int getJdbcTypeCount() {
return 1;
}
@Override
default List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
default List<JdbcMapping> getJdbcMappings() {
return Collections.singletonList( getJdbcMapping() );
}

View File

@ -11,26 +11,7 @@ import org.hibernate.sql.results.graph.Fetchable;
/**
* @author Steve Ebersole
*/
public interface BasicValuedModelPart extends BasicValuedMapping, ModelPart, Fetchable {
/**
* The table expression (table name or subselect) that contains
* the {@linkplain #getMappedColumnExpression mapped column}
*/
String getContainingTableExpression();
/**
* The column expression (column name or formula) to which this basic value
* is mapped
*/
String getMappedColumnExpression();
default boolean isMappedColumnExpressionFormula() {
return false;
}
String getCustomReadExpression();
String getCustomWriteExpression();
public interface BasicValuedModelPart extends BasicValuedMapping, ModelPart, Fetchable, SelectionMapping {
@Override
default MappingType getPartMappingType() {

View File

@ -8,13 +8,11 @@ package org.hibernate.metamodel.mapping;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Contract for things at the domain/mapping level that can be bound into a JDBC
@ -43,24 +41,13 @@ public interface Bindable {
* }
*/
default int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
final MutableInteger value = new MutableInteger();
visitJdbcTypes(
sqlExpressableType -> value.incrementAndGet(),
Clause.IRRELEVANT,
typeConfiguration
);
return value.get();
default int getJdbcTypeCount() {
return forEachJdbcType( (index, jdbcMapping) -> {} );
}
default List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
default List<JdbcMapping> getJdbcMappings() {
final List<JdbcMapping> results = new ArrayList<>();
visitJdbcTypes(
results::add,
Clause.IRRELEVANT,
typeConfiguration
);
forEachJdbcType( (index, jdbcMapping) -> results.add( jdbcMapping ) );
return results;
}
@ -71,10 +58,12 @@ public interface Bindable {
* <p>
* Used during cacheable SQL AST creation.
*/
default void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
default int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
return forEachJdbcType( 0, action );
}
default int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
throw new NotYetImplementedFor6Exception( getClass() );
}
@ -143,11 +132,20 @@ public interface Bindable {
*
* Think of it as breaking the multi-dimensional array into a visitable flat array
*/
default void visitDisassembledJdbcValues(
default int forEachDisassembledJdbcValue(
Object value,
Clause clause,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return forEachDisassembledJdbcValue( value, clause, 0, valuesConsumer, session );
}
default int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
throw new NotYetImplementedFor6Exception( getClass() );
}
@ -155,16 +153,25 @@ public interface Bindable {
* Visit each constituent JDBC value extracted from the entity instance itself.
*
* Short-hand form of calling {@link #disassemble} and piping its result to
* {@link #visitDisassembledJdbcValues}
* {@link #forEachDisassembledJdbcValue}
*
* todo (6.0) : Would this would ever be used?
*/
default void visitJdbcValues(
default int forEachJdbcValue(
Object value,
Clause clause,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
visitDisassembledJdbcValues( disassemble( value, session ), clause, valuesConsumer, session );
return forEachJdbcValue( value, clause, 0, valuesConsumer, session );
}
default int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return forEachDisassembledJdbcValue( disassemble( value, session ), clause, offset, valuesConsumer, session );
}
@ -176,6 +183,6 @@ public interface Bindable {
/**
* Consume a JDBC-level jdbcValue. The JDBC jdbcMapping descriptor is also passed in
*/
void consume(Object jdbcValue, JdbcMapping jdbcMapping);
void consume(int selectionIndex, Object jdbcValue, JdbcMapping jdbcMapping);
}
}

View File

@ -1,23 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.mapping;
/**
* Consumer used to visit columns for a given model part
*
* @author Steve Ebersole
*/
@FunctionalInterface
public interface ColumnConsumer {
void accept(
String containingTableExpression,
String columnExpression,
boolean isFormula,
String customReadExpression,
String customWriteExpression,
JdbcMapping jdbcMapping);
}

View File

@ -6,7 +6,10 @@
*/
package org.hibernate.metamodel.mapping;
import java.util.Collection;
import java.util.List;
import org.hibernate.mapping.IndexedConsumer;
/**
* Support for composite identifier mappings
@ -22,5 +25,12 @@ public interface CompositeIdentifierMapping extends EntityIdentifierMapping {
/**
* The attributes associated with this composite
*/
Collection<SingularAttributeMapping> getAttributes();
List<SingularAttributeMapping> getAttributes();
default void forEachAttribute(IndexedConsumer<SingularAttributeMapping> consumer) {
final List<SingularAttributeMapping> attributes = getAttributes();
for ( int i = 0; i < attributes.size(); i++ ) {
consumer.accept( i, attributes.get( i ) );
}
}
}

View File

@ -8,30 +8,36 @@ package org.hibernate.metamodel.mapping;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Table;
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
import org.hibernate.metamodel.mapping.internal.SelectionMappingsImpl;
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
@ -61,42 +67,21 @@ import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class EmbeddableMappingType implements ManagedMappingType {
public class EmbeddableMappingType implements ManagedMappingType, SelectionMappings {
public static EmbeddableMappingType from(
Component bootDescriptor,
CompositeType compositeType,
Function<EmbeddableMappingType,EmbeddableValuedModelPart> embeddedPartBuilder,
MappingModelCreationProcess creationProcess) {
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
final EmbeddableRepresentationStrategy representationStrategy = creationContext.getBootstrapContext()
.getRepresentationStrategySelector()
.resolveStrategy( bootDescriptor, creationContext );
final EmbeddableMappingType mappingType = new EmbeddableMappingType(
bootDescriptor,
representationStrategy,
embeddedPartBuilder,
creationContext.getSessionFactory()
);
creationProcess.registerInitializationCallback(
"EmbeddableMappingType#finishInitialization",
() -> mappingType.finishInitialization(
bootDescriptor,
compositeType,
creationProcess
)
);
return mappingType;
return from( bootDescriptor, compositeType, null, null, embeddedPartBuilder, creationProcess );
}
public static EmbeddableMappingType from(
Component bootDescriptor,
CompositeType compositeType,
NavigableRole embeddedRole,
String rootTableExpression,
String[] rootTableKeyColumnNames,
Function<EmbeddableMappingType,EmbeddableValuedModelPart> embeddedPartBuilder,
MappingModelCreationProcess creationProcess) {
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
@ -113,10 +98,12 @@ public class EmbeddableMappingType implements ManagedMappingType {
);
creationProcess.registerInitializationCallback(
"EmbeddableMappingType(" + embeddedRole + ")#finishInitialization",
"EmbeddableMappingType(" + bootDescriptor.getRoleName() + ")#finishInitialization",
() -> mappingType.finishInitialization(
bootDescriptor,
compositeType,
rootTableExpression,
rootTableKeyColumnNames,
creationProcess
)
);
@ -130,7 +117,9 @@ public class EmbeddableMappingType implements ManagedMappingType {
private final SessionFactoryImplementor sessionFactory;
// private final Map<String,AttributeMapping> attributeMappings = new TreeMap<>();
private final Map<String,AttributeMapping> attributeMappings = new LinkedHashMap<>();
private final List<AttributeMapping> attributes = new ArrayList<>();
private final Map<String, AttributeMapping> attributeMap = new HashMap<>();
private SelectionMappings selectionMappings;
private final EmbeddableValuedModelPart valueMapping;
private NavigableRole embeddedRole;
@ -162,13 +151,14 @@ public class EmbeddableMappingType implements ManagedMappingType {
private boolean finishInitialization(
Component bootDescriptor,
CompositeType compositeType,
String rootTableExpression,
String[] rootTableKeyColumnNames,
MappingModelCreationProcess creationProcess) {
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
final String containingTableExpression = valueMapping.getContainingTableExpression();
final List<String> mappedColumnExpressions = valueMapping.getMappedColumnExpressions();
final String baseTableExpression = valueMapping.getContainingTableExpression();
final Dialect dialect = creationProcess.getCreationContext().getSessionFactory().getJdbcServices().getDialect();
final Type[] subtypes = compositeType.getSubtypes();
int attributeIndex = 0;
@ -183,12 +173,31 @@ public class EmbeddableMappingType implements ManagedMappingType {
if ( subtype instanceof BasicType ) {
final BasicValue basicValue = (BasicValue) bootPropertyDescriptor.getValue();
final Selectable selectable = basicValue.getColumn();
final String containingTableExpression;
final String columnExpression;
if ( rootTableKeyColumnNames == null ) {
if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, creationProcess.getSqmFunctionRegistry() );
}
else {
columnExpression = selectable.getText( dialect );
}
if ( selectable instanceof Column ) {
containingTableExpression = getTableIdentifierExpression(
( (Column) selectable ).getValue().getTable(),
creationProcess
);
}
else {
containingTableExpression = baseTableExpression;
}
}
else {
containingTableExpression = rootTableExpression;
columnExpression = rootTableKeyColumnNames[columnPosition];
}
final String mappedColumnExpression = mappedColumnExpressions.get( columnPosition++ );
attributeMappings.put(
bootPropertyDescriptor.getName(),
MappingModelCreationHelper.buildBasicAttributeMapping(
BasicValuedSingularAttributeMapping attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
bootPropertyDescriptor.getName(),
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
attributeIndex,
@ -196,15 +205,16 @@ public class EmbeddableMappingType implements ManagedMappingType {
this,
(BasicType<?>) subtype,
containingTableExpression,
mappedColumnExpression,
false,
columnExpression,
selectable.isFormula(),
selectable.getCustomReadExpression(),
selectable.getCustomWriteExpression(),
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex ),
creationProcess
)
);
addAttribute( attributeMapping );
columnPosition++;
}
else if ( subtype instanceof AnyType ) {
final Any bootValueMapping = (Any) bootPropertyDescriptor.getValue();
@ -292,9 +302,7 @@ public class EmbeddableMappingType implements ManagedMappingType {
}
};
attributeMappings.put(
bootPropertyDescriptor.getName(),
new DiscriminatedAssociationAttributeMapping(
DiscriminatedAssociationAttributeMapping attributeMapping = new DiscriminatedAssociationAttributeMapping(
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Object.class ),
this,
@ -306,65 +314,58 @@ public class EmbeddableMappingType implements ManagedMappingType {
anyType,
bootValueMapping,
creationProcess
)
);
addAttribute( attributeMapping );
}
else if ( subtype instanceof CompositeType ) {
final CompositeType subCompositeType = (CompositeType) subtype;
final int columnSpan = subCompositeType.getColumnSpan( sessionFactory );
final List<String> customReadExpressions = new ArrayList<>( columnSpan );
final List<String> customWriteExpressions = new ArrayList<>( columnSpan );
final Iterator<Selectable> columnIterator = bootDescriptor.getColumnIterator();
while ( columnIterator.hasNext() ) {
final Selectable selectable = columnIterator.next();
customReadExpressions.add( selectable.getCustomReadExpression() );
customWriteExpressions.add( selectable.getCustomWriteExpression() );
final String subTableExpression;
final String[] subRootTableKeyColumnNames;
if ( rootTableKeyColumnNames == null ) {
subTableExpression = baseTableExpression;
subRootTableKeyColumnNames = null;
}
else {
subTableExpression = rootTableExpression;
subRootTableKeyColumnNames = new String[columnSpan];
System.arraycopy( rootTableKeyColumnNames, columnPosition, subRootTableKeyColumnNames, 0, columnSpan );
}
attributeMappings.put(
bootPropertyDescriptor.getName(),
MappingModelCreationHelper.buildEmbeddedAttributeMapping(
EmbeddedAttributeMapping attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
bootPropertyDescriptor.getName(),
attributeIndex,
bootPropertyDescriptor,
this,
subCompositeType,
containingTableExpression,
ArrayHelper.toStringArray( mappedColumnExpressions.subList( columnPosition, columnPosition + columnSpan ) ),
// ArrayHelper.toStringArray( customReadExpressions.subList( columnPosition, columnPosition + columnSpan ) ),
// ArrayHelper.toStringArray( customWriteExpressions.subList( columnPosition, columnPosition + columnSpan ) ),
ArrayHelper.toStringArray( customReadExpressions ),
ArrayHelper.toStringArray( customWriteExpressions ),
subTableExpression,
subRootTableKeyColumnNames,
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex ),
creationProcess
)
);
addAttribute( attributeMapping );
columnPosition += columnSpan;
}
else {
final EntityPersister entityPersister = creationProcess
.getEntityPersister( bootDescriptor.getOwner().getEntityName() );
if ( subtype instanceof CollectionType ) {
attributeMappings.put(
bootPropertyDescriptor.getName(),
MappingModelCreationHelper.buildPluralAttributeMapping(
PluralAttributeMapping attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
bootPropertyDescriptor.getName(),
attributeIndex,
bootPropertyDescriptor,
entityPersister,
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
compositeType.getCascadeStyle( attributeIndex),
compositeType.getCascadeStyle( attributeIndex ),
compositeType.getFetchMode( attributeIndex ),
creationProcess
)
);
addAttribute( attributeMapping );
}
else if ( subtype instanceof EntityType ) {
final ToOneAttributeMapping toOneAttributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
final int columnSpan = subtype.getColumnSpan( sessionFactory );
final ToOneAttributeMapping attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
bootPropertyDescriptor.getName(),
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
attributeIndex,
@ -375,18 +376,53 @@ public class EmbeddableMappingType implements ManagedMappingType {
compositeType.getCascadeStyle( attributeIndex ),
creationProcess
);
attributeMappings.put( bootPropertyDescriptor.getName(), toOneAttributeMapping );
// todo (6.0) : not sure it is always correct
columnPosition++;
addAttribute( attributeMapping );
columnPosition += columnSpan;
}
}
attributeIndex++;
}
// We need the attribute mapping types to finish initialization first before we can build the column mappings
creationProcess.registerInitializationCallback(
"EmbeddableMappingType(" + embeddedRole + ")#initColumnMappings",
this::initColumnMappings
);
return true;
}
private static String getTableIdentifierExpression(Table table, MappingModelCreationProcess creationProcess) {
final JdbcEnvironment jdbcEnvironment = creationProcess.getCreationContext()
.getMetadata()
.getDatabase()
.getJdbcEnvironment();
return jdbcEnvironment
.getQualifiedObjectNameFormatter().format(
table.getQualifiedTableName(),
jdbcEnvironment.getDialect()
);
}
private boolean initColumnMappings() {
this.selectionMappings = SelectionMappingsImpl.from( this );
return true;
}
private void addAttribute(AttributeMapping attributeMapping) {
if ( attributeMap.put( attributeMapping.getAttributeName(), attributeMapping ) == null ) {
attributes.add( attributeMapping );
}
else {
for ( ListIterator<AttributeMapping> iterator = attributes.listIterator(); iterator.hasNext(); ) {
final AttributeMapping existingMapping = iterator.next();
if ( existingMapping.getAttributeName().equals( attributeMapping.getAttributeName() ) ) {
iterator.set( attributeMapping );
break;
}
}
}
}
public EmbeddableValuedModelPart getEmbeddedValueMapping() {
return valueMapping;
@ -435,7 +471,7 @@ public class EmbeddableMappingType implements ManagedMappingType {
@Override
public int getNumberOfFetchables() {
return attributeMappings.size();
return attributeMap.size();
}
@Override
@ -445,115 +481,82 @@ public class EmbeddableMappingType implements ManagedMappingType {
visitAttributeMappings( attributeMapping -> fetchableConsumer.accept( (Fetchable) attributeMapping ) );
}
private int cachedJdbcTypeCount = -1;
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
if ( cachedJdbcTypeCount == -1 ) {
int count = 0;
for ( AttributeMapping attributeMapping : getAttributeMappings() ) {
count += attributeMapping.getJdbcTypeCount( typeConfiguration );
}
this.cachedJdbcTypeCount = count;
}
return cachedJdbcTypeCount;
}
private List<JdbcMapping> cachedJdbcMappings;
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
if ( cachedJdbcMappings == null ) {
final List<JdbcMapping> result = new ArrayList<>();
visitJdbcTypes(
result::add,
Clause.IRRELEVANT,
typeConfiguration
);
this.cachedJdbcMappings = Collections.unmodifiableList( result );
}
return cachedJdbcMappings;
public SelectionMapping getSelectionMapping(int columnIndex) {
return selectionMappings.getSelectionMapping( columnIndex );
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
attributeMappings.forEach(
(s, attributeMapping) -> {
if ( attributeMapping instanceof PluralAttributeMapping ) {
return;
public int getJdbcTypeCount() {
return selectionMappings.getJdbcTypeCount();
}
if ( attributeMapping instanceof ToOneAttributeMapping ) {
( (ToOneAttributeMapping) attributeMapping ).getKeyTargetMatchPart().visitJdbcTypes(
action,
clause,
typeConfiguration
);
}
else {
attributeMapping.visitJdbcTypes( action, clause, typeConfiguration );
@Override
public List<JdbcMapping> getJdbcMappings() {
return selectionMappings.getJdbcMappings();
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return selectionMappings.forEachSelection(
offset,
(selectionIndex, selectionMapping) -> {
action.accept( selectionIndex, selectionMapping.getJdbcMapping() );
}
);
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
final Collection<AttributeMapping> attributeMappings = getAttributeMappings();
Object[] result = new Object[attributeMappings.size()];
int i = 0;
final Iterator<AttributeMapping> iterator = attributeMappings.iterator();
while ( iterator.hasNext() ) {
AttributeMapping mapping = iterator.next();
Object[] result = new Object[attributes.size()];
for ( int i = 0; i < attributes.size(); i++ ) {
AttributeMapping mapping = attributes.get( i );
Object o = mapping.getPropertyAccess().getGetter().get( value );
result[i] = mapping.disassemble( o, session );
i++;
}
return result;
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer consumer,
SharedSessionContractImplementor session) {
attributeMappings.forEach(
(s, attributeMapping) -> {
Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
attributeMapping.visitJdbcValues( o, clause, consumer, session );
int span = 0;
for ( int i = 0; i < attributes.size(); i++ ) {
final AttributeMapping attributeMapping = attributes.get( i );
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
span += attributeMapping.forEachJdbcValue( o, clause, span + offset, consumer, session );
}
);
return span;
}
@Override
public void visitDisassembledJdbcValues(
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
final Collection<AttributeMapping> attributeMappings = getAttributeMappings();
final Iterator<AttributeMapping> iterator = attributeMappings.iterator();
final Object[] values = (Object[]) value;
int i = 0;
while ( iterator.hasNext() ) {
AttributeMapping mapping = iterator.next();
mapping.visitDisassembledJdbcValues( values[i], clause, valuesConsumer, session );
i++;
int span = 0;
for ( int i = 0; i < attributes.size(); i++ ) {
final AttributeMapping mapping = attributes.get( i );
span += mapping.forEachDisassembledJdbcValue( values[i], clause, span + offset, valuesConsumer, session );
}
return span;
}
public void visitColumns(ColumnConsumer consumer) {
attributeMappings.values().forEach(
attributeMapping -> attributeMapping.visitColumns( consumer )
);
@Override
public int forEachSelection(SelectionConsumer consumer) {
return selectionMappings.forEachSelection( 0, consumer );
}
@Override
public int forEachSelection(int offset, SelectionConsumer consumer) {
return selectionMappings.forEachSelection( offset, consumer );
}
@Override
@ -563,27 +566,34 @@ public class EmbeddableMappingType implements ManagedMappingType {
@Override
public int getNumberOfAttributeMappings() {
return attributeMappings.size();
return attributeMap.size();
}
@Override
public AttributeMapping findAttributeMapping(String name) {
return attributeMappings.get( name );
return attributeMap.get( name );
}
@Override
public Collection<AttributeMapping> getAttributeMappings() {
return attributeMappings.values();
public List<AttributeMapping> getAttributeMappings() {
return attributes;
}
@Override
public void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
for ( int i = 0; i < attributes.size(); i++ ) {
consumer.accept( i, attributes.get( i ) );
}
}
@Override
public void visitAttributeMappings(Consumer<AttributeMapping> action) {
attributeMappings.values().forEach( action );
attributes.forEach( action );
}
@Override
public ModelPart findSubPart(String name, EntityMappingType treatTargetType) {
return attributeMappings.get( name );
return attributeMap.get( name );
}
@Override
@ -595,22 +605,15 @@ public class EmbeddableMappingType implements ManagedMappingType {
public void setPropertyValues(Object compositeInstance, Object[] resolvedValues) {
// todo (6.0) : reflection optimizer...
visitAttributeMappings(
new Consumer<AttributeMapping>() {
private int i = 0;
@Override
public void accept(AttributeMapping attributeMapping) {
attributeMapping.getAttributeMetadataAccess()
for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i )
.getAttributeMetadataAccess()
.resolveAttributeMetadata( null )
.getPropertyAccess()
.getSetter()
.set( compositeInstance, resolvedValues[i++], sessionFactory );
.set( compositeInstance, resolvedValues[i], sessionFactory );
}
}
);
}
public boolean isCreateEmptyCompositesEnabled() {
return createEmptyCompositesEnabled;

View File

@ -8,11 +8,12 @@ package org.hibernate.metamodel.mapping;
import java.util.List;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.spi.SqlAstCreationState;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer;
@ -29,25 +30,68 @@ import org.hibernate.sql.results.graph.FetchableContainer;
* @author Steve Ebersole
*/
public interface EmbeddableValuedModelPart extends ModelPart, Fetchable, FetchableContainer, TableGroupJoinProducer {
EmbeddableMappingType getEmbeddableTypeDescriptor();
@Override
default int getJdbcTypeCount() {
return getEmbeddableTypeDescriptor().getJdbcTypeCount();
}
@Override
default List<JdbcMapping> getJdbcMappings() {
return getEmbeddableTypeDescriptor().getJdbcMappings();
}
@Override
default int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return getEmbeddableTypeDescriptor().forEachJdbcType( offset, action );
}
@Override
default int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().forEachJdbcValue( value, clause, offset, valuesConsumer, session );
}
@Override
default int forEachSelection(int offset, SelectionConsumer consumer) {
return getEmbeddableTypeDescriptor().forEachSelection( offset, consumer );
}
@Override
default int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().forEachDisassembledJdbcValue(
value,
clause,
offset,
valuesConsumer,
session
);
}
@Override
default Object disassemble(Object value, SharedSessionContractImplementor session) {
return getEmbeddableTypeDescriptor().disassemble( value, session );
}
/**
* The table expression (table name or subselect) that contains
* the columns to which this embedded is mapped.
* The main table expression (table name or subselect) that usually contains
* most of the columns to which this embedded is mapped.
*
* @apiNote Hibernate has historically required a composite to be mapped to the same table.
*/
String getContainingTableExpression();
/**
* The column expressions (column name or formula) to which this embedded value
* is mapped
*/
List<String> getMappedColumnExpressions();
List<String> getCustomReadExpressions();
List<String> getCustomWriteExpressions();
/**
* @see org.hibernate.annotations.Parent
*/

View File

@ -7,6 +7,7 @@
package org.hibernate.metamodel.mapping;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
@ -177,7 +178,7 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
}
interface ConstraintOrderedTableConsumer {
void consume(String tableExpression, Supplier<Consumer<ColumnConsumer>> tableKeyColumnVisitationSupplier);
void consume(String tableExpression, Supplier<Consumer<SelectionConsumer>> tableKeyColumnVisitationSupplier);
}
@ -195,16 +196,11 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
final Object[] values = new Object[ getNumberOfAttributeMappings() ];
visitStateArrayContributors(
new Consumer<StateArrayContributorMapping>() {
private int index;
@Override
public void accept(StateArrayContributorMapping attribute) {
attribute -> {
final DomainResultAssembler assembler = assemblerMapping.get( attribute );
final Object value = assembler == null ? UNFETCHED_PROPERTY : assembler.assemble( rowProcessingState );
values[index++] = value;
}
values[attribute.getStateArrayPosition()] = value;
}
);
@ -288,7 +284,7 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel
}
@Override
default Collection<AttributeMapping> getAttributeMappings() {
default List<AttributeMapping> getAttributeMappings() {
return getEntityPersister().getAttributeMappings();
}

View File

@ -6,16 +6,17 @@
*/
package org.hibernate.metamodel.mapping;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -59,19 +60,23 @@ public interface EntityValuedModelPart extends FetchableContainer {
}
@Override
default int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return getEntityMappingType().getJdbcTypeCount( typeConfiguration );
default int getJdbcTypeCount() {
int span = 0;
final List<AttributeMapping> attributeMappings = getEntityMappingType().getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
span += attributeMappings.get( i ).getJdbcTypeCount();
}
return span;
}
@Override
default void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
getEntityMappingType().getAttributeMappings().forEach(
attributeMapping ->
attributeMapping.visitJdbcTypes( action, clause, typeConfiguration )
);
default int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
int span = 0;
final List<AttributeMapping> attributeMappings = getEntityMappingType().getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
span += attributeMappings.get( i ).forEachJdbcType( span + offset, action );
}
return span;
}
@Override
@ -80,22 +85,28 @@ public interface EntityValuedModelPart extends FetchableContainer {
}
@Override
default void visitDisassembledJdbcValues(
default int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
getEntityMappingType().visitDisassembledJdbcValues( value, clause, valuesConsumer, session );
return getEntityMappingType().forEachDisassembledJdbcValue( value, clause, offset, valuesConsumer, session );
}
@Override
default void visitJdbcValues(
default int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer consumer,
SharedSessionContractImplementor session) {
getEntityMappingType().getAttributeMappings().forEach(
attributeMapping ->
attributeMapping.visitJdbcValues( value, clause, consumer, session )
); }
int span = 0;
final List<AttributeMapping> attributeMappings = getEntityMappingType().getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
final AttributeMapping attributeMapping = attributeMappings.get( i );
span += attributeMapping.forEachJdbcValue( value, clause, span + offset, consumer, session );
}
return span;
}
}

View File

@ -55,13 +55,21 @@ public interface ForeignKeyDescriptor extends VirtualModelPart {
* Visits the FK "referring" columns
*/
@Override
default void visitColumns(ColumnConsumer consumer) {
visitReferringColumns( consumer );
default int forEachSelection(int offset, SelectionConsumer consumer) {
return visitReferringColumns( offset, consumer );
}
void visitReferringColumns(ColumnConsumer consumer);
int visitReferringColumns(int offset, SelectionConsumer consumer);
void visitTargetColumns(ColumnConsumer consumer);
int visitTargetColumns(int offset, SelectionConsumer consumer);
default int visitReferringColumns(SelectionConsumer consumer) {
return visitReferringColumns( 0, consumer );
}
default int visitTargetColumns(SelectionConsumer consumer) {
return visitTargetColumns( 0, consumer );
}
AssociationKey getAssociationKey();
}

View File

@ -7,8 +7,10 @@
package org.hibernate.metamodel.mapping;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -41,13 +43,23 @@ public interface ManagedMappingType extends MappingType, FetchableContainer {
/**
* Get access to the attributes defined on this class and any supers
*/
Collection<AttributeMapping> getAttributeMappings();
List<AttributeMapping> getAttributeMappings();
/**
* Visit attributes defined on this class and any supers
*/
void visitAttributeMappings(Consumer<AttributeMapping> action);
/**
* Visit attributes defined on this class and any supers
*/
default void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
final List<AttributeMapping> attributeMappings = getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
consumer.accept( i, attributeMappings.get( i ) );
}
}
/**
* @todo (6.0) : consider dropping this in favor of a form passing the ManagedMappingType
* which indicates the type to limit the attribute search to (the type and its super-type)

View File

@ -25,34 +25,26 @@ public class MappingModelHelper {
ModelPart modelPart,
SqlExpressionResolver sqlExpressionResolver,
SessionFactoryImplementor sessionFactory) {
final int jdbcTypeCount = modelPart.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
if ( modelPart instanceof EmbeddableValuedModelPart ) {
final List<ColumnReference> columnReferences = new ArrayList<>( jdbcTypeCount );
modelPart.visitColumns(
(table, column, isFormula, readFragment, writeFragment, jdbcMapping) -> {
modelPart.forEachSelection(
(columnIndex, selection) -> {
final ColumnReference colRef;
if ( sqlExpressionResolver == null ) {
colRef = new ColumnReference(
table,
column,
isFormula,
readFragment,
writeFragment,
jdbcMapping,
selection.getContainingTableExpression(),
selection,
sessionFactory
);
}
else {
colRef = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( table, column ),
createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
table,
column,
isFormula,
readFragment,
writeFragment,
jdbcMapping,
selection.getContainingTableExpression(),
selection,
sessionFactory
)
);
@ -68,24 +60,16 @@ public class MappingModelHelper {
if ( sqlExpressionResolver == null ) {
return new ColumnReference(
basicPart.getContainingTableExpression(),
basicPart.getMappedColumnExpression(),
basicPart.isMappedColumnExpressionFormula(),
basicPart.getCustomReadExpression(),
basicPart.getCustomWriteExpression(),
basicPart.getJdbcMapping(),
basicPart,
sessionFactory
);
}
else {
return sqlExpressionResolver.resolveSqlExpression(
createColumnReferenceKey( basicPart.getContainingTableExpression(), basicPart.getMappedColumnExpression() ),
createColumnReferenceKey( basicPart.getContainingTableExpression(), basicPart.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
basicPart.getContainingTableExpression(),
basicPart.getMappedColumnExpression(),
basicPart.isMappedColumnExpressionFormula(),
basicPart.getCustomReadExpression(),
basicPart.getCustomWriteExpression(),
basicPart.getJdbcMapping(),
basicPart,
sessionFactory
)
);

View File

@ -94,8 +94,12 @@ public interface ModelPart extends MappingModelExpressable {
throw new NotYetImplementedFor6Exception( getClass() );
}
default void visitColumns(ColumnConsumer consumer) {
default int forEachSelection(SelectionConsumer consumer) {
return forEachSelection( 0, consumer );
}
default int forEachSelection(int offset, SelectionConsumer consumer) {
return 0;
}
EntityMappingType findContainingEntityMapping();

View File

@ -0,0 +1,62 @@
/*
* 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;
/**
* Consumer used to visit columns for a given model part
*
* @author Steve Ebersole
*/
@FunctionalInterface
public interface SelectionConsumer {
void accept(int selectionIndex, SelectionMapping selectionMapping);
default void accept(String tableName, String[] columnNames) {
class SelectionMappingIterator implements SelectionMapping {
private int index;
@Override
public String getContainingTableExpression() {
return tableName;
}
@Override
public String getSelectionExpression() {
return columnNames[index];
}
@Override
public String getCustomReadExpression() {
return null;
}
@Override
public String getCustomWriteExpression() {
return null;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public JdbcMapping getJdbcMapping() {
return null;
}
}
for (
SelectionMappingIterator iterator = new SelectionMappingIterator();
iterator.index < columnNames.length;
iterator.index++
) {
accept( iterator.index, iterator );
}
}
}

View File

@ -0,0 +1,21 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.mapping;
/**
* A column mapping.
*
* @author Christian Beikov
*/
public interface SelectionMapping {
String getContainingTableExpression();
String getSelectionExpression();
String getCustomReadExpression();
String getCustomWriteExpression();
boolean isFormula();
JdbcMapping getJdbcMapping();
}

View File

@ -0,0 +1,33 @@
/*
* 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;
import java.util.ArrayList;
import java.util.List;
/**
* A container for multiple column mappings.
*
* @author Christian Beikov
*/
public interface SelectionMappings {
SelectionMapping getSelectionMapping(int columnIndex);
int getJdbcTypeCount();
int forEachSelection(int offset, SelectionConsumer consumer);
default int forEachSelection(SelectionConsumer consumer) {
return forEachSelection( 0, consumer );
}
default List<JdbcMapping> getJdbcMappings() {
final List<JdbcMapping> results = new ArrayList<>();
forEachSelection( (index, selection) -> results.add( selection.getJdbcMapping() ) );
return results;
}
}

View File

@ -122,23 +122,19 @@ public abstract class AbstractDomainPath implements DomainPath {
SqlExpressionResolver sqlExprResolver) {
if ( embeddableValuedModelPart.getFetchableName()
.equals( modelPartName ) || ELEMENT_TOKEN.equals( modelPartName ) ) {
embeddableValuedModelPart.visitColumns(
(tableExpression, columnExpression, isFormula, customReadExpression, customWriteExpression, jdbcMapping) -> {
final TableReference tableReference = tableGroup.resolveTableReference( tableExpression );
embeddableValuedModelPart.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = tableGroup.resolveTableReference( selection.getContainingTableExpression() );
ast.addSortSpecification(
new SortSpecification(
sqlExprResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableExpression,
columnExpression
selection.getContainingTableExpression(),
selection.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableReference,
columnExpression,
isFormula,
customReadExpression,
customWriteExpression,
jdbcMapping,
selection,
sessionFactory
)
),
@ -176,11 +172,7 @@ public abstract class AbstractDomainPath implements DomainPath {
new SortSpecification(
new ColumnReference(
tableReference,
basicValuedPart.getMappedColumnExpression(),
basicValuedPart.isMappedColumnExpressionFormula(),
basicValuedPart.getCustomReadExpression(),
basicValuedPart.getCustomWriteExpression(),
basicValuedPart.getJdbcMapping(),
basicValuedPart,
creationState.getCreationContext().getSessionFactory()
),
collation,

View File

@ -34,6 +34,7 @@ public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscri
private final EntityPersister entityDescriptor;
private final String tableExpression;
private final String mappedColumnExpression;
private final boolean isFormula;
private final BasicType mappingType;
@ -41,10 +42,12 @@ public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscri
EntityPersister entityDescriptor,
String tableExpression,
String mappedColumnExpression,
boolean isFormula,
BasicType mappingType) {
this.entityDescriptor = entityDescriptor;
this.tableExpression = tableExpression;
this.mappedColumnExpression = mappedColumnExpression;
this.isFormula = isFormula;
this.mappingType = mappingType;
}
@ -58,10 +61,15 @@ public abstract class AbstractEntityDiscriminatorMapping implements EntityDiscri
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return mappedColumnExpression;
}
@Override
public boolean isFormula() {
return isFormula;
}
@Override
public String getFetchableName() {
return ROLE_NAME;

View File

@ -10,6 +10,7 @@ import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
@ -82,10 +83,15 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return column;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public String getCustomReadExpression() {
return null;
@ -136,6 +142,12 @@ public class AnyDiscriminatorPart implements BasicValuedModelPart, FetchOptions
return this;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, jdbcMapping() );
return getJdbcTypeCount();
}
@Override
public Fetch generateFetch(
FetchParent fetchParent,

View File

@ -8,15 +8,15 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -37,7 +37,6 @@ import org.hibernate.sql.results.graph.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Acts as a ModelPart for the key portion of an any-valued mapping
@ -74,10 +73,15 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return column;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public String getCustomReadExpression() {
return null;
@ -193,34 +197,30 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
}
@Override
public void visitColumns(ColumnConsumer consumer) {
consumer.accept( table, column, false, null, null, jdbcMapping );
public int forEachSelection(int offset, SelectionConsumer consumer) {
consumer.accept( offset, this );
return getJdbcTypeCount();
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> consumer,
Clause clause,
TypeConfiguration typeConfiguration) {
consumer.accept( jdbcMapping );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, jdbcMapping );
return getJdbcTypeCount();
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( value, jdbcMapping );
valuesConsumer.consume( offset, value, jdbcMapping );
return getJdbcTypeCount();
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return 1;
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
public List<JdbcMapping> getJdbcMappings() {
return Collections.singletonList( jdbcMapping );
}
}

View File

@ -7,18 +7,18 @@
package org.hibernate.metamodel.mapping.internal;
import java.util.Locale;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -44,7 +44,6 @@ import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Andrea Boriero
@ -130,21 +129,9 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return 1;
}
@Override
public void visitColumns(ColumnConsumer consumer) {
consumer.accept(
getContainingTableExpression(),
getMappedColumnExpression(),
// identifiers cannot be formula nor can they define custom read/write expressions
false,
null,
null,
getJdbcMapping()
);
public int forEachSelection(int offset, SelectionConsumer consumer) {
consumer.accept( offset, this );
return getJdbcTypeCount();
}
@Override
@ -153,20 +140,20 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
action.accept( idType );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, idType );
return getJdbcTypeCount();
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( value, idType );
valuesConsumer.consume( offset, value, idType );
return getJdbcTypeCount();
}
@Override
@ -268,10 +255,15 @@ public class BasicEntityIdentifierMappingImpl implements BasicEntityIdentifierMa
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return pkColumnName;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public String getCustomReadExpression() {
return null;

View File

@ -8,15 +8,16 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.SelectionMapping;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -40,9 +41,6 @@ import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
import static org.hibernate.metamodel.relational.RuntimeRelationModelHelper.DEFAULT_COLUMN_WRITE_EXPRESSION;
/**
* Models a basic collection element/value or index/key
@ -54,32 +52,20 @@ public class BasicValuedCollectionPart
private final NavigableRole navigableRole;
private final CollectionPersister collectionDescriptor;
private final Nature nature;
private final JdbcMapping mapper;
private final BasicValueConverter valueConverter;
private final String tableExpression;
private final String columnExpression;
private final String customColumnReadExpr;
private final String customColumnWriteExpr;
private final SelectionMapping selectionMapping;
public BasicValuedCollectionPart(
CollectionPersister collectionDescriptor,
Nature nature,
JdbcMapping mapper,
BasicValueConverter valueConverter,
String tableExpression,
String columnExpression,
String customColumnReadExpr,
String customColumnWriteExpr) {
SelectionMapping selectionMapping) {
this.navigableRole = collectionDescriptor.getNavigableRole().append( nature.getName() );
this.collectionDescriptor = collectionDescriptor;
this.nature = nature;
this.mapper = mapper;
this.valueConverter = valueConverter;
this.tableExpression = tableExpression;
this.columnExpression = columnExpression;
this.customColumnReadExpr = customColumnReadExpr;
this.customColumnWriteExpr = customColumnWriteExpr;
this.selectionMapping = selectionMapping;
}
@Override
@ -89,27 +75,32 @@ public class BasicValuedCollectionPart
@Override
public MappingType getPartMappingType() {
return mapper::getJavaTypeDescriptor;
return selectionMapping.getJdbcMapping()::getJavaTypeDescriptor;
}
@Override
public String getContainingTableExpression() {
return tableExpression;
return selectionMapping.getContainingTableExpression();
}
@Override
public String getMappedColumnExpression() {
return columnExpression;
public String getSelectionExpression() {
return selectionMapping.getSelectionExpression();
}
@Override
public boolean isFormula() {
return selectionMapping.isFormula();
}
@Override
public String getCustomReadExpression() {
return null;
return selectionMapping.getCustomReadExpression();
}
@Override
public String getCustomWriteExpression() {
return null;
return selectionMapping.getCustomWriteExpression();
}
@Override
@ -119,7 +110,7 @@ public class BasicValuedCollectionPart
@Override
public JavaTypeDescriptor getJavaTypeDescriptor() {
return mapper.getJavaTypeDescriptor();
return selectionMapping.getJdbcMapping().getJavaTypeDescriptor();
}
@Override
@ -150,14 +141,13 @@ public class BasicValuedCollectionPart
return exprResolver.resolveSqlSelection(
exprResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableGroup.getPrimaryTableReference(), columnExpression ),
SqlExpressionResolver.createColumnReferenceKey(
tableGroup.getPrimaryTableReference(),
selectionMapping.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
columnExpression,
false,
customColumnReadExpr,
customColumnWriteExpr,
mapper,
selectionMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
@ -179,7 +169,7 @@ public class BasicValuedCollectionPart
@Override
public JdbcMapping getJdbcMapping() {
return mapper;
return selectionMapping.getJdbcMapping();
}
@Override
@ -235,12 +225,7 @@ public class BasicValuedCollectionPart
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return 1;
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
public List<JdbcMapping> getJdbcMappings() {
return Collections.singletonList( getJdbcMapping() );
}
@ -255,27 +240,26 @@ public class BasicValuedCollectionPart
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
action.accept( getJdbcMapping() );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, selectionMapping.getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public void visitColumns(ColumnConsumer consumer) {
consumer.accept(
tableExpression,
columnExpression,
false,
customColumnReadExpr,
customColumnWriteExpr,
getJdbcMapping()
);
public int forEachSelection(int offset, SelectionConsumer consumer) {
consumer.accept( offset, selectionMapping );
return getJdbcTypeCount();
}
@Override
public void visitDisassembledJdbcValues(
Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
valuesConsumer.consume( value, getJdbcMapping() );
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( offset, value, getJdbcMapping() );
return getJdbcTypeCount();
}
@Override

View File

@ -6,14 +6,13 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.ConvertibleModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ManagedMappingType;
@ -38,7 +37,6 @@ import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -117,12 +115,12 @@ public class BasicValuedSingularAttributeMapping
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return mappedColumnExpression;
}
@Override
public boolean isMappedColumnExpressionFormula() {
public boolean isFormula() {
return isFormula;
}
@ -175,20 +173,15 @@ public class BasicValuedSingularAttributeMapping
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
final String tableAlias = tableReference.getIdentificationVariable();
final String columnExpression = getMappedColumnExpression();
return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
columnExpression
mappedColumnExpression
),
sqlAstProcessingState -> new ColumnReference(
tableAlias,
columnExpression,
isMappedColumnExpressionFormula(),
customReadExpression,
customWriteExpression,
jdbcMapping,
this,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
@ -211,15 +204,11 @@ public class BasicValuedSingularAttributeMapping
expressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
getMappedColumnExpression()
mappedColumnExpression
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
getMappedColumnExpression(),
isMappedColumnExpressionFormula(),
customReadExpression,
customWriteExpression,
jdbcMapping,
this,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
@ -268,31 +257,25 @@ public class BasicValuedSingularAttributeMapping
}
@Override
public void visitDisassembledJdbcValues(
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( value, getJdbcMapping() );
valuesConsumer.consume( offset, value, getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
action.accept( getJdbcMapping() );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, jdbcMapping );
return getJdbcTypeCount();
}
@Override
public void visitColumns(ColumnConsumer consumer) {
consumer.accept(
tableExpression,
mappedColumnExpression,
isFormula,
customReadExpression,
customWriteExpression,
jdbcMapping
);
public int forEachSelection(int offset, SelectionConsumer consumer) {
consumer.accept( offset, this );
return getJdbcTypeCount();
}
}

View File

@ -10,6 +10,7 @@ import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.CollectionIdentifierDescriptor;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -67,10 +68,15 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return columnName;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public String getCustomReadExpression() {
return null;
@ -121,6 +127,12 @@ public class CollectionIdentifierDescriptorImpl implements CollectionIdentifierD
return this;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public Fetch generateFetch(
FetchParent fetchParent,

View File

@ -10,7 +10,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
@ -20,7 +19,8 @@ import org.hibernate.loader.ast.internal.CompoundNaturalIdLoader;
import org.hibernate.loader.ast.internal.MultiNaturalIdLoaderStandard;
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
import org.hibernate.loader.ast.spi.NaturalIdLoader;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
@ -32,7 +32,6 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Multi-attribute NaturalIdMapping implementation
@ -56,10 +55,9 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
this.attributes = attributes;
final List<JdbcMapping> jdbcMappings = new ArrayList<>();
final TypeConfiguration typeConfiguration = creationProcess.getCreationContext().getTypeConfiguration();
attributes.forEach(
(attribute) -> attribute.visitJdbcTypes( jdbcMappings::add, Clause.IRRELEVANT, typeConfiguration )
);
for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i ).forEachJdbcType( (index, jdbcMapping) -> jdbcMappings.add( jdbcMapping ) );
}
this.jdbcMappings = jdbcMappings;
loader = new CompoundNaturalIdLoader<>(
@ -133,23 +131,25 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
@Override
public void applySqlSelections(NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState) {
attributes.forEach(
(attribute) -> attribute.applySqlSelections( navigablePath, tableGroup, creationState )
);
for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i ).applySqlSelections( navigablePath, tableGroup, creationState );
}
}
@Override
public void applySqlSelections(NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState, BiConsumer<SqlSelection, JdbcMapping> selectionConsumer) {
attributes.forEach(
(attribute) -> attribute.applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer )
);
for ( int i = 0; i < attributes.size(); i++ ) {
attributes.get( i ).applySqlSelections( navigablePath, tableGroup, creationState, selectionConsumer );
}
}
@Override
public void visitColumns(ColumnConsumer consumer) {
attributes.forEach(
(attribute) -> attribute.visitColumns( consumer )
);
public int forEachSelection(int offset, SelectionConsumer consumer) {
int span = 0;
for ( int i = 0; i < attributes.size(); i++ ) {
span += attributes.get( i ).forEachSelection( span + offset, consumer );
}
return span;
}
@ -157,18 +157,22 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
// Bindable
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
public int getJdbcTypeCount() {
return jdbcMappings.size();
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
public List<JdbcMapping> getJdbcMappings() {
return jdbcMappings;
}
@Override
public void visitJdbcTypes(Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
jdbcMappings.forEach( action );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
int span = 0;
for ( ; span < jdbcMappings.size(); span++ ) {
action.accept( span + offset, jdbcMappings.get( span ) );
}
return span;
}
@Override
@ -189,28 +193,41 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
}
@Override
public void visitDisassembledJdbcValues(Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
assert value instanceof Object[];
final Object[] incoming = (Object[]) value;
assert incoming.length == attributes.size();
int span = 0;
for ( int i = 0; i < attributes.size(); i++ ) {
final SingularAttributeMapping attribute = attributes.get( i );
attribute.visitDisassembledJdbcValues( incoming[ i ], clause, valuesConsumer, session );
span += attribute.forEachDisassembledJdbcValue( incoming[ i ], clause, span + offset, valuesConsumer, session );
}
return span;
}
@Override
public void visitJdbcValues(Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
assert value instanceof Object[];
final Object[] incoming = (Object[]) value;
assert incoming.length == attributes.size();
int span = 0;
for ( int i = 0; i < attributes.size(); i++ ) {
final SingularAttributeMapping attribute = attributes.get( i );
attribute.visitJdbcValues( incoming[ i ], clause, valuesConsumer, session );
span += attribute.forEachJdbcValue( incoming[ i ], clause, span + offset, valuesConsumer, session );
}
return span;
}
}

View File

@ -13,10 +13,12 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ManagedMappingType;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.ModelPart;
@ -128,6 +130,17 @@ public class DiscriminatedAssociationAttributeMapping
return 2;
}
@Override
public int getJdbcTypeCount() {
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
int span = getDiscriminatorPart().forEachJdbcType( offset, action );
return span + getKeyPart().forEachJdbcType( offset + span, action );
}
@Override
public void visitFetchables(Consumer<Fetchable> fetchableConsumer, EntityMappingType treatTargetType) {
fetchableConsumer.accept( getDiscriminatorPart() );

View File

@ -74,7 +74,9 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
final Selectable metaColumn = columnIterator.next();
assert columnIterator.hasNext();
final Selectable keyColumn = columnIterator.next();
assert ! columnIterator.hasNext();
assert !columnIterator.hasNext();
assert !metaColumn.isFormula();
assert !keyColumn.isFormula();
final AnyDiscriminatorPart discriminatorPart = new AnyDiscriminatorPart(
containerRole.append( AnyDiscriminatorPart.ROLE_NAME),

View File

@ -11,10 +11,12 @@ import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.DiscriminatedAssociationModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.model.domain.NavigableRole;
@ -164,4 +166,15 @@ public class DiscriminatedCollectionPart implements DiscriminatedAssociationMode
public int getNumberOfFetchables() {
return 2;
}
@Override
public int getJdbcTypeCount() {
return getDiscriminatorPart().getJdbcTypeCount() + getKeyPart().getJdbcTypeCount();
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
int span = getDiscriminatorPart().forEachJdbcType( offset, action );
return span + getKeyPart().forEachJdbcType( offset + span, action );
}
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@ -16,7 +15,8 @@ import org.hibernate.engine.FetchStrategy;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -49,7 +49,6 @@ import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -60,9 +59,6 @@ public class EmbeddedAttributeMapping
private final NavigableRole navigableRole;
private final String tableExpression;
private final String[] attrColumnNames;
private final String[] customReadExpressions;
private final String[] customWriteExpressions;
private final EmbeddableMappingType embeddableMappingType;
private final PropertyAccess parentInjectionAttributePropertyAccess;
@ -72,9 +68,6 @@ public class EmbeddedAttributeMapping
NavigableRole navigableRole,
int stateArrayPosition,
String tableExpression,
String[] attrColumnNames,
String[] customReadExpressions,
String[] customWriteExpressions,
StateArrayContributorMetadataAccess attributeMetadataAccess,
String parentInjectionAttributeName,
FetchStrategy mappedFetchStrategy,
@ -102,9 +95,6 @@ public class EmbeddedAttributeMapping
}
this.tableExpression = tableExpression;
this.attrColumnNames = attrColumnNames;
this.customReadExpressions = customReadExpressions;
this.customWriteExpressions = customWriteExpressions;
this.embeddableMappingType = embeddableMappingType;
}
@ -124,46 +114,14 @@ public class EmbeddedAttributeMapping
return tableExpression;
}
@Override
public List<String> getMappedColumnExpressions() {
return Arrays.asList( attrColumnNames );
}
@Override
public List<String> getCustomReadExpressions() {
return Arrays.asList( customReadExpressions );
}
@Override
public List<String> getCustomWriteExpressions() {
return Arrays.asList( customWriteExpressions );
}
@Override
public PropertyAccess getParentInjectionAttributePropertyAccess() {
return parentInjectionAttributePropertyAccess;
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
getEmbeddableTypeDescriptor().visitJdbcTypes( action, clause, typeConfiguration );
}
@Override
public void visitJdbcValues(
Object value,
Clause clause,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
getEmbeddableTypeDescriptor().visitJdbcValues( value, clause, valuesConsumer, session );
}
@Override
public void visitColumns(ColumnConsumer consumer) {
getEmbeddableTypeDescriptor().visitColumns( consumer );
public int forEachSelection(int offset, SelectionConsumer consumer) {
return getEmbeddableTypeDescriptor().forEachSelection( offset, consumer );
}
@Override
@ -228,41 +186,27 @@ public class EmbeddedAttributeMapping
Clause clause,
SqmToSqlAstConverter walker,
SqlAstCreationState sqlAstCreationState) {
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( attrColumnNames.length );
final TableReference tableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
getEmbeddableTypeDescriptor().visitJdbcTypes(
new Consumer<JdbcMapping>() {
private int position = -1;
@Override
public void accept(JdbcMapping jdbcMapping) {
position++;
final String attrColumnExpr = attrColumnNames[ position ];
final String attrColumnCustomReadExpr = customReadExpressions[ position ];
final String attrColumnCustomWriteExpr = customWriteExpressions[ position ];
final List<ColumnReference> columnReferences = CollectionHelper.arrayList( embeddableMappingType.getJdbcTypeCount() );
final TableReference defaultTableReference = tableGroup.resolveTableReference( getContainingTableExpression() );
getEmbeddableTypeDescriptor().forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = selection.getContainingTableExpression().equals( defaultTableReference.getTableExpression() )
? defaultTableReference
: tableGroup.resolveTableReference( selection.getContainingTableExpression() );
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
attrColumnExpr
selection.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
attrColumnExpr,
false,
attrColumnCustomReadExpr,
attrColumnCustomWriteExpr,
jdbcMapping,
selection,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
);
columnReferences.add( (ColumnReference) columnReference );
}
},
clause,
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
);
return new SqlTuple( columnReferences, this );

View File

@ -14,8 +14,9 @@ import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -49,7 +50,6 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -61,9 +61,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
private final EmbeddableMappingType embeddableMappingType;
private final String containingTableExpression;
private final List<String> columnExpressions;
private final List<String> customReadExpressions;
private final List<String> customWriteExpressions;
private final PropertyAccess parentInjectionAttributePropertyAccess;
private final String sqlAliasStem;
@ -75,12 +72,7 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
EmbeddableMappingType embeddableMappingType,
String parentInjectionAttributeName,
String containingTableExpression,
List<String> columnExpressions,
List<String> customReadExpressions,
List<String> customWriteExpressions,
String sqlAliasStem) {
this.customReadExpressions = customReadExpressions;
this.customWriteExpressions = customWriteExpressions;
this.navigableRole = collectionDescriptor.getNavigableRole().appendContainer( nature.getName() );
this.collectionDescriptor = collectionDescriptor;
this.nature = nature;
@ -96,7 +88,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
this.embeddableMappingType = embeddableMappingType;
this.containingTableExpression = containingTableExpression;
this.columnExpressions = columnExpressions;
this.sqlAliasStem = sqlAliasStem;
}
@ -134,21 +125,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
return containingTableExpression;
}
@Override
public List<String> getMappedColumnExpressions() {
return columnExpressions;
}
@Override
public List<String> getCustomReadExpressions() {
return customReadExpressions;
}
@Override
public List<String> getCustomWriteExpressions() {
return customWriteExpressions;
}
@Override
public PropertyAccess getParentInjectionAttributePropertyAccess() {
return parentInjectionAttributePropertyAccess;
@ -164,31 +140,6 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
return this;
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return getEmbeddableTypeDescriptor().getJdbcTypeCount( typeConfiguration );
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
return getEmbeddableTypeDescriptor().getJdbcMappings( typeConfiguration );
}
@Override
public void visitJdbcTypes(Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
getEmbeddableTypeDescriptor().visitJdbcTypes( action, clause, typeConfiguration );
}
@Override
public void visitJdbcValues(
Object value,
Clause clause,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
getEmbeddableTypeDescriptor().visitJdbcValues( value, clause, valuesConsumer, session );
}
@Override
public Fetch generateFetch(
FetchParent fetchParent,
@ -218,20 +169,15 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final List<Expression> expressions = new ArrayList<>();
getEmbeddableTypeDescriptor().visitColumns(
(tableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) ->{
assert containingTableExpression.equals( tableExpression );
assert columnExpressions.contains( columnExpression );
getEmbeddableTypeDescriptor().forEachSelection(
(columnIndex, selection) -> {
assert containingTableExpression.equals( selection.getContainingTableExpression() );
expressions.add(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableExpression, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( selection.getContainingTableExpression(), selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableGroup.resolveTableReference( tableExpression ),
columnExpression,
isFormula,
readFragment,
writeFragment,
jdbcMapping,
tableGroup.resolveTableReference( selection.getContainingTableExpression() ),
selection,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
)
@ -310,8 +256,4 @@ public class EmbeddedCollectionPart implements CollectionPart, EmbeddableValuedF
return FetchTiming.IMMEDIATE;
}
@Override
public void visitColumns(ColumnConsumer consumer) {
getEmbeddableTypeDescriptor().visitColumns( consumer );
}
}

View File

@ -8,23 +8,21 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.AssociationKey;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.SelectionMappings;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
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.SingularAttributeMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
@ -45,64 +43,43 @@ import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableForeignKeyResultImpl;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Andrea Boriero
*/
public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, ModelPart {
private final AbstractCompositeIdentifierMapping mappingType;
private final EmbeddableValuedModelPart mappingType;
private final String keyColumnContainingTable;
private final List<String> keyColumnExpressions;
private final SelectionMappings keySelectionMappings;
private final String targetColumnContainingTable;
private final List<String> targetColumnExpressions;
private final List<JdbcMapping> jdbcMappings;
private final SelectionMappings targetSelectionMappings;
private AssociationKey associationKey;
public EmbeddedForeignKeyDescriptor(
AbstractCompositeIdentifierMapping mappingType,
EmbeddableValuedModelPart mappingType,
String keyColumnContainingTable,
List<String> keyColumnExpressions,
SelectionMappings keySelectionMappings,
String targetColumnContainingTable,
List<String> targetColumnExpressions,
SelectionMappings targetSelectionMappings,
MappingModelCreationProcess creationProcess) {
this.keyColumnContainingTable = keyColumnContainingTable;
this.keyColumnExpressions = keyColumnExpressions;
this.keySelectionMappings = keySelectionMappings;
this.targetColumnContainingTable = targetColumnContainingTable;
this.targetColumnExpressions = targetColumnExpressions;
this.targetSelectionMappings = targetSelectionMappings;
this.mappingType = mappingType;
jdbcMappings = new ArrayList<>();
creationProcess.registerInitializationCallback(
"Embedded (composite) FK descriptor " + mappingType.getNavigableRole(),
() -> {
// todo (6.0) : how to make sure things we need are ready to go?
// - e.g., here, we need access to the sub-attributes
final Collection<SingularAttributeMapping> subAttributes = mappingType.getAttributes();
final List<AttributeMapping> subAttributes = mappingType.getEmbeddableTypeDescriptor().getAttributeMappings();
if ( subAttributes.isEmpty() ) {
// todo (6.0) : ^^ for now, this is the only way we "know" that the embeddable has not been finalized yet
return false;
}
subAttributes.forEach(
attribute -> {
final TypeConfiguration typeConfiguration = creationProcess
.getCreationContext()
.getTypeConfiguration();
if ( attribute instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping associationAttributeMapping = (ToOneAttributeMapping) attribute;
associationAttributeMapping.getAssociatedEntityMappingType()
.getEntityPersister()
.getIdentifierMapping()
.visitJdbcTypes( jdbcMappings::add, null, typeConfiguration );
}
else {
attribute.visitJdbcTypes( jdbcMappings::add, null, typeConfiguration );
}
}
);
return true;
}
);
@ -119,37 +96,35 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
final String identificationVariable = tableReference.getIdentificationVariable();
List<SqlSelection> sqlSelections = new ArrayList<>();
for ( int i = 0; i < keyColumnExpressions.size(); i++ ) {
final JdbcMapping jdbcMapping = jdbcMappings.get( i );
final String columnExpression = targetColumnExpressions.get( i );
List<SqlSelection> sqlSelections = new ArrayList<>( targetSelectionMappings.getJdbcTypeCount() );
targetSelectionMappings.forEachSelection(
(columnIndex, selection) -> {
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
columnExpression
selection.getSelectionExpression()
),
s ->
new ColumnReference(
identificationVariable,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
creationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
selection.getJdbcMapping().getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext()
.getDomainModel()
.getTypeConfiguration()
);
sqlSelections.add( sqlSelection );
}
);
return new EmbeddableForeignKeyResultImpl(
return new EmbeddableForeignKeyResultImpl<>(
sqlSelections,
collectionPath,
mappingType,
@ -172,37 +147,32 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
final String identificationVariable = tableReference.getIdentificationVariable();
int size = keyColumnExpressions.size();
List<SqlSelection> sqlSelections = new ArrayList<>( size );
for ( int i = 0; i < size; i++ ) {
final String columnExpression = keyColumnExpressions.get( i );
final JdbcMapping jdbcMapping = jdbcMappings.get( i );
List<SqlSelection> sqlSelections = new ArrayList<>( keySelectionMappings.getJdbcTypeCount() );
keySelectionMappings.forEachSelection(
(columnIndex, selection) -> {
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
columnExpression
selection.getSelectionExpression()
),
s ->
new ColumnReference(
identificationVariable,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
creationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
selection.getJdbcMapping().getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
);
sqlSelections.add( sqlSelection );
}
);
return new EmbeddableForeignKeyResultImpl(
return new EmbeddableForeignKeyResultImpl<>(
sqlSelections,
collectionPath,
mappingType,
@ -259,11 +229,11 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
final String lhsTableExpression = lhs.getTableExpression();
if ( lhsTableExpression.equals( keyColumnContainingTable ) ) {
assert rhsTableExpression.equals( targetColumnContainingTable );
return getPredicate( lhs, rhs, creationContext, keyColumnExpressions, targetColumnExpressions );
return getPredicate( lhs, rhs, creationContext, keySelectionMappings, targetSelectionMappings );
}
else {
assert rhsTableExpression.equals( keyColumnContainingTable );
return getPredicate( lhs, rhs, creationContext, targetColumnExpressions, keyColumnExpressions );
return getPredicate( lhs, rhs, creationContext, targetSelectionMappings, keySelectionMappings );
}
}
@ -271,34 +241,27 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
TableReference lhs,
TableReference rhs,
SqlAstCreationContext creationContext,
List<String> lhsExpressions,
List<String> rhsColumnExpressions) {
SelectionMappings lhsMappings,
SelectionMappings rhsMappings) {
final Junction predicate = new Junction( Junction.Nature.CONJUNCTION );
for ( int i = 0; i < lhsExpressions.size(); i++ ) {
final JdbcMapping jdbcMapping = jdbcMappings.get( i );
lhsMappings.forEachSelection(
(i, selection) -> {
final ComparisonPredicate comparisonPredicate = new ComparisonPredicate(
new ColumnReference(
lhs,
lhsExpressions.get( i ),
false,
null,
null,
jdbcMapping,
selection,
creationContext.getSessionFactory()
),
ComparisonOperator.EQUAL,
new ColumnReference(
rhs,
rhsColumnExpressions.get( i ),
false,
null,
null,
jdbcMapping,
rhsMappings.getSelectionMapping( i ),
creationContext.getSessionFactory()
)
);
predicate.add( comparisonPredicate );
}
);
return predicate;
}
@ -336,37 +299,25 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
}
@Override
public void visitReferringColumns(ColumnConsumer consumer) {
for ( int i = 0; i < keyColumnExpressions.size(); i++ ) {
consumer.accept(
keyColumnContainingTable,
keyColumnExpressions.get( i ),
false,
null,
null,
jdbcMappings.get( i )
);
}
public int visitReferringColumns(int offset, SelectionConsumer consumer) {
return keySelectionMappings.forEachSelection( offset, consumer );
}
@Override
public void visitTargetColumns(ColumnConsumer consumer) {
for ( int i = 0; i < keyColumnExpressions.size(); i++ ) {
consumer.accept(
targetColumnContainingTable,
targetColumnExpressions.get( i ),
false,
null,
null,
jdbcMappings.get( i )
);
}
public int visitTargetColumns(int offset, SelectionConsumer consumer) {
return targetSelectionMappings.forEachSelection( offset, consumer );
}
@Override
public AssociationKey getAssociationKey() {
if ( associationKey == null ) {
associationKey = new AssociationKey( keyColumnContainingTable, keyColumnExpressions );
final List<String> columns = new ArrayList<>();
keySelectionMappings.forEachSelection(
(columnIndex, selection) -> {
columns.add( selection.getSelectionExpression() );
}
);
associationKey = new AssociationKey( keyColumnContainingTable, columns );
}
return associationKey;
}
@ -397,37 +348,33 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
final String identificationVariable = tableReference.getIdentificationVariable();
int size = keyColumnExpressions.size();
List<SqlSelection> sqlSelections = new ArrayList<>( size );
for ( int i = 0; i < size; i++ ) {
final String columnExpression = keyColumnExpressions.get( i );
final JdbcMapping jdbcMapping = jdbcMappings.get( i );
final int size = keySelectionMappings.getJdbcTypeCount();
final List<SqlSelection> sqlSelections = new ArrayList<>( size );
keySelectionMappings.forEachSelection(
(columnIndex, selection) -> {
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
columnExpression
selection.getSelectionExpression()
),
s ->
new ColumnReference(
identificationVariable,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
creationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
selection.getJdbcMapping().getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
);
sqlSelections.add( sqlSelection );
}
);
return new EmbeddableForeignKeyResultImpl(
return new EmbeddableForeignKeyResultImpl<>(
sqlSelections,
navigablePath,
mappingType,
@ -442,18 +389,18 @@ public class EmbeddedForeignKeyDescriptor implements ForeignKeyDescriptor, Model
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
mappingType.visitJdbcTypes( action, clause, typeConfiguration );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return mappingType.forEachJdbcType( offset, action );
}
@Override
public void visitDisassembledJdbcValues(
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
mappingType.visitDisassembledJdbcValues( value, clause, valuesConsumer, session );
return mappingType.forEachDisassembledJdbcValue( value, clause, offset, valuesConsumer, session );
}
@Override

View File

@ -7,12 +7,11 @@
package org.hibernate.metamodel.mapping.internal;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
@ -39,14 +38,12 @@ public class EmbeddedIdentifierMappingImpl extends AbstractCompositeIdentifierMa
StateArrayContributorMetadataAccess attributeMetadataAccess,
PropertyAccess propertyAccess,
String tableExpression,
String[] attrColumnNames,
SessionFactoryImplementor sessionFactory) {
super(
attributeMetadataAccess,
embeddableDescriptor,
entityMapping,
tableExpression,
attrColumnNames,
sessionFactory
);
@ -97,8 +94,8 @@ public class EmbeddedIdentifierMappingImpl extends AbstractCompositeIdentifierMa
@Override
@SuppressWarnings( { "unchecked", "rawtypes" } )
public Collection<SingularAttributeMapping> getAttributes() {
return (Collection) getEmbeddableTypeDescriptor().getAttributeMappings();
public List<SingularAttributeMapping> getAttributes() {
return (List) getEmbeddableTypeDescriptor().getAttributeMappings();
}
@Override
@ -112,27 +109,30 @@ public class EmbeddedIdentifierMappingImpl extends AbstractCompositeIdentifierMa
}
@Override
public void visitDisassembledJdbcValues(
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
getEmbeddableTypeDescriptor().visitDisassembledJdbcValues( value, clause, valuesConsumer, session );
return getEmbeddableTypeDescriptor().forEachDisassembledJdbcValue(
value,
clause,
offset,
valuesConsumer,
session
);
}
@Override
public Object disassemble(Object value, SharedSessionContractImplementor session) {
final Collection<SingularAttributeMapping> attributeMappings = getAttributes();
Object[] result = new Object[attributeMappings.size()];
int i = 0;
final Iterator<SingularAttributeMapping> iterator = attributeMappings.iterator();
while ( iterator.hasNext() ) {
AttributeMapping mapping = iterator.next();
final Object[] result = new Object[getAttributeCount()];
forEachAttribute(
(i, mapping) -> {
Object o = mapping.getPropertyAccess().getGetter().get( value );
result[i] = mapping.disassemble( o, session );
i++;
}
);
return result;
}
}

View File

@ -13,7 +13,7 @@ import org.hibernate.engine.FetchTiming;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
@ -170,8 +170,8 @@ public class EntityCollectionPart
}
@Override
public void visitColumns(ColumnConsumer consumer) {
entityMappingType.visitColumns( consumer );
public int forEachSelection(int offset, SelectionConsumer consumer) {
return entityMappingType.forEachSelection( offset, consumer );
}
@Override

View File

@ -6,8 +6,10 @@
*/
package org.hibernate.metamodel.mapping.internal;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -28,8 +30,9 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
EntityPersister entityDescriptor,
String tableExpression,
String mappedColumnExpression,
boolean isFormula,
BasicType mappingType) {
super( entityDescriptor, tableExpression, mappedColumnExpression, mappingType );
super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType );
this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
}
@ -44,15 +47,11 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
expressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
getMappedColumnExpression()
getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
getMappedColumnExpression(),
false,
null,
null,
getJdbcMapping(),
this,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
@ -61,6 +60,12 @@ public class EntityDiscriminatorMappingImpl extends AbstractEntityDiscriminatorM
);
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public NavigableRole getNavigableRole() {
return navigableRole;

View File

@ -8,6 +8,7 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.function.BiConsumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityRowIdMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -110,6 +111,17 @@ public class EntityRowIdMappingImpl implements EntityRowIdMapping {
);
}
@Override
public int getJdbcTypeCount() {
return 1;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, JavaObjectType.INSTANCE );
return getJdbcTypeCount();
}
@Override
public void applySqlSelections(
NavigablePath navigablePath, TableGroup tableGroup, DomainResultCreationState creationState) {

View File

@ -11,7 +11,8 @@ import java.util.function.BiConsumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -72,10 +73,15 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
}
@Override
public String getMappedColumnExpression() {
public String getSelectionExpression() {
return columnExpression;
}
@Override
public boolean isFormula() {
return false;
}
@Override
public String getCustomReadExpression() {
return null;
@ -227,11 +233,6 @@ public class EntityVersionMappingImpl implements EntityVersionMapping, FetchOpti
}
@Override
public void visitColumns(ColumnConsumer consumer) {
}
@Override
public FetchStyle getStyle() {
return FetchStyle.JOIN;

View File

@ -8,8 +8,10 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.List;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
@ -32,10 +34,11 @@ public class JoinedSubclassDiscriminatorMappingImpl extends AbstractEntityDiscri
EntityPersister entityDescriptor,
String tableExpression,
String mappedColumnExpression,
boolean isFormula,
CaseSearchedExpression caseSearchedExpression,
List<ColumnReference> columnReferences,
BasicType mappingType) {
super( entityDescriptor, tableExpression, mappedColumnExpression, mappingType );
super( entityDescriptor, tableExpression, mappedColumnExpression, isFormula, mappingType );
this.navigableRole = entityDescriptor.getNavigableRole().append( EntityDiscriminatorMapping.ROLE_NAME );
this.caseSearchedExpression = caseSearchedExpression;
@ -61,7 +64,7 @@ public class JoinedSubclassDiscriminatorMappingImpl extends AbstractEntityDiscri
return expressionResolver.resolveSqlSelection(
expressionResolver.resolveSqlExpression(
getMappedColumnExpression(),
getSelectionExpression(),
sqlAstProcessingState -> caseSearchedExpression
),
getMappedType().getMappedJavaTypeDescriptor(),
@ -88,4 +91,10 @@ public class JoinedSubclassDiscriminatorMappingImpl extends AbstractEntityDiscri
public String getCustomWriteExpression() {
return null;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, getJdbcMapping() );
return getJdbcTypeCount();
}
}

View File

@ -32,7 +32,6 @@ import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Collection;
@ -50,11 +49,12 @@ import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
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.SelectionMapping;
import org.hibernate.metamodel.mapping.SelectionMappings;
import org.hibernate.metamodel.mapping.CompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
@ -128,6 +128,8 @@ public class MappingModelCreationHelper {
final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
(Component) bootProperty.getValue(),
cidType,
rootTableName,
rootTableKeyColumnNames,
embeddable -> new EmbeddedIdentifierMappingImpl(
entityPersister,
attributeName,
@ -135,7 +137,6 @@ public class MappingModelCreationHelper {
attributeMetadataAccess,
propertyAccess,
rootTableName,
rootTableKeyColumnNames,
creationProcess.getCreationContext().getSessionFactory()
),
creationProcess
@ -158,6 +159,8 @@ public class MappingModelCreationHelper {
final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
bootIdClassComponent,
cidType,
rootTableName,
rootTableKeyColumnNames,
attributeMappingType -> {
final SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
final PropertyAccess propertyAccess = PropertyAccessStrategyMapImpl.INSTANCE.buildPropertyAccess(
@ -260,7 +263,6 @@ public class MappingModelCreationHelper {
idAttributeMappings,
attributeMetadataAccess,
rootTableName,
rootTableKeyColumnNames,
bootIdClassComponent,
bootComponentDescriptor,
creationProcess
@ -418,9 +420,7 @@ public class MappingModelCreationHelper {
ManagedMappingType declaringType,
CompositeType attrType,
String tableExpression,
String[] attrColumnNames,
String[] attrColCustomReadExprs,
String[] attrColCustomWriteExprs,
String[] rootTableKeyColumnNames,
PropertyAccess propertyAccess,
CascadeStyle cascadeStyle,
MappingModelCreationProcess creationProcess) {
@ -436,14 +436,13 @@ public class MappingModelCreationHelper {
final EmbeddableMappingType embeddableMappingType = EmbeddableMappingType.from(
component,
attrType,
tableExpression,
rootTableKeyColumnNames,
attributeMappingType -> new EmbeddedAttributeMapping(
attrName,
declaringType.getNavigableRole().append( attrName ),
stateArrayPosition,
tableExpression,
attrColumnNames,
attrColCustomReadExprs,
attrColCustomWriteExprs,
attributeMetadataAccess,
component.getParentProperty(),
FetchStrategy.IMMEDIATE_JOIN,
@ -650,17 +649,19 @@ public class MappingModelCreationHelper {
);
final BasicValue index = (BasicValue) ( (IndexedCollection) bootValueMapping ).getIndex();
final Selectable column = index.getColumnIterator().next();
final SelectionMapping selectionMapping = SelectionMappingImpl.from(
tableExpression,
index.getColumnIterator().next(),
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
dialect,
creationProcess.getSqmFunctionRegistry()
);
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
// no converter
null,
tableExpression,
column.getText( dialect ),
column.getCustomReadExpression(),
column.getCustomWriteExpression()
selectionMapping
);
break;
@ -699,17 +700,19 @@ public class MappingModelCreationHelper {
}
case LIST: {
final BasicValue index = (BasicValue) ( (IndexedCollection) bootValueMapping ).getIndex();
final SelectionMapping selectionMapping = SelectionMappingImpl.from(
tableExpression,
index.getColumnIterator().next(),
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
dialect,
creationProcess.getSqmFunctionRegistry()
);
indexDescriptor = new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
creationContext.getTypeConfiguration().getBasicTypeForJavaType( Integer.class ),
// no converter
null,
tableExpression,
index.getColumnIterator().next().getText( dialect ),
null,
null
selectionMapping
);
collectionMappingType = new CollectionMappingTypeImpl(
@ -908,13 +911,18 @@ public class MappingModelCreationHelper {
assert bootValueMappingKey.getColumnSpan() == 1;
assert fkTarget instanceof BasicValuedModelPart;
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final String tableExpression = getTableIdentifierExpression( bootValueMappingKey.getTable(), creationProcess );
final SelectionMapping keySelectionMapping = SelectionMappingImpl.from(
tableExpression,
bootValueMappingKey.getColumnIterator().next(),
(JdbcMapping) keyType,
dialect,
creationProcess.getSqmFunctionRegistry()
);
attributeMapping.setForeignKeyDescriptor(
new SimpleForeignKeyDescriptor(
getTableIdentifierExpression( bootValueMappingKey.getTable(), creationProcess ),
bootValueMappingKey.getColumnIterator().next().getText( dialect ),
simpleFkTarget.getContainingTableExpression(),
simpleFkTarget.getMappedColumnExpression(),
(JdbcMapping) keyType
keySelectionMapping,
simpleFkTarget
)
);
}
@ -950,7 +958,8 @@ public class MappingModelCreationHelper {
final ForeignKeyDirection foreignKeyDirection = ( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection();
attributeMapping.setForeignKeyDirection( foreignKeyDirection );
attributeMapping.setIdentifyingColumnsTableExpression( bootValueMapping.getTable().getName() );
final String tableName = getTableIdentifierExpression( bootValueMapping.getTable(), creationProcess );
attributeMapping.setIdentifyingColumnsTableExpression( tableName );
final EntityPersister referencedEntityDescriptor = creationProcess
.getEntityPersister( bootValueMapping.getReferencedEntityName() );
@ -961,17 +970,33 @@ public class MappingModelCreationHelper {
}
if ( referencedPropertyName != null ) {
final ToOneAttributeMapping referencedAttributeMapping =
(ToOneAttributeMapping) referencedEntityDescriptor.findSubPart( referencedPropertyName );
final ModelPart modelPart = referencedEntityDescriptor.findSubPart( referencedPropertyName );
if ( modelPart instanceof ToOneAttributeMapping ) {
setRefererencedAttributeForeignKeyDescriptor(
attributeMapping,
referencedAttributeMapping,
(ToOneAttributeMapping) modelPart,
referencedEntityDescriptor,
referencedPropertyName,
dialect,
creationProcess
);
}
else if ( modelPart instanceof EmbeddableValuedModelPart ) {
final EmbeddedForeignKeyDescriptor embeddedForeignKeyDescriptor = buildEmbeddedForeignKeyDescriptor(
(EmbeddableValuedModelPart) modelPart,
attributeMapping,
bootValueMapping,
dialect,
creationProcess
);
attributeMapping.setForeignKeyDescriptor( embeddedForeignKeyDescriptor );
}
else {
throw new NotYetImplementedFor6Exception(
"Support for composite foreign-keys not yet implemented: " +
bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName()
);
}
return;
}
@ -984,24 +1009,34 @@ public class MappingModelCreationHelper {
}
if ( fkTarget instanceof BasicValuedModelPart ) {
final String keyColumnExpression;
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
final Table table = bootValueMapping.getTable();
final String tableExpression = getTableIdentifierExpression( table, creationProcess );
final SelectionMapping keySelectionMapping;
if ( columnIterator.hasNext() ) {
keyColumnExpression = columnIterator.next().getText( dialect );
keySelectionMapping = SelectionMappingImpl.from(
tableExpression,
columnIterator.next(),
simpleFkTarget.getJdbcMapping(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
}
else {
// case of ToOne with @PrimaryKeyJoinColumn
keyColumnExpression = table.getColumn( 0 ).getName();
keySelectionMapping = SelectionMappingImpl.from(
tableExpression,
table.getColumn( 0 ),
simpleFkTarget.getJdbcMapping(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
}
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
final ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(
getTableIdentifierExpression( table, creationProcess ),
keyColumnExpression,
simpleFkTarget.getContainingTableExpression(),
simpleFkTarget.getMappedColumnExpression(),
simpleFkTarget.getJdbcMapping()
keySelectionMapping,
simpleFkTarget
);
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
}
@ -1029,34 +1064,41 @@ public class MappingModelCreationHelper {
Value bootValueMapping,
Dialect dialect,
MappingModelCreationProcess creationProcess) {
final List<String> mappedColumnExpressions = fkTarget.getMappedColumnExpressions();
final List<String> targetColumnExpressions = new ArrayList<>( mappedColumnExpressions.size() );
targetColumnExpressions.addAll( mappedColumnExpressions );
final List<String> keyColumnExpressions;
Table keyTableExpression;
final SelectionMappings keySelectionMappings;
final String keyTableExpression;
if ( bootValueMapping instanceof Collection ) {
final Collection collectionBootValueMapping = (Collection) bootValueMapping;
keyTableExpression = collectionBootValueMapping.getCollectionTable();
final KeyValue key = collectionBootValueMapping.getKey();
keyColumnExpressions = new ArrayList<>( key.getColumnSpan() );
key.getColumnIterator().forEachRemaining(
column ->
keyColumnExpressions.add( column.getText( dialect ) ) );
keyTableExpression = getTableIdentifierExpression(
collectionBootValueMapping.getCollectionTable(),
creationProcess
);
keySelectionMappings = SelectionMappingsImpl.from(
keyTableExpression,
collectionBootValueMapping.getKey(),
creationProcess.getCreationContext().getSessionFactory(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
}
else {
keyTableExpression = bootValueMapping.getTable();
keyColumnExpressions = new ArrayList<>( bootValueMapping.getColumnSpan() );
bootValueMapping.getColumnIterator().forEachRemaining(
column ->
keyColumnExpressions.add( column.getText( dialect ) ) );
keyTableExpression = getTableIdentifierExpression(
bootValueMapping.getTable(),
creationProcess
);
keySelectionMappings = SelectionMappingsImpl.from(
keyTableExpression,
bootValueMapping,
creationProcess.getCreationContext().getSessionFactory(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
}
return new EmbeddedForeignKeyDescriptor(
(AbstractCompositeIdentifierMapping) fkTarget,
getTableIdentifierExpression( keyTableExpression, creationProcess ),
keyColumnExpressions,
fkTarget,
keyTableExpression,
keySelectionMappings,
fkTarget.getContainingTableExpression(),
targetColumnExpressions,
fkTarget.getEmbeddableTypeDescriptor(),
creationProcess
);
}
@ -1115,16 +1157,18 @@ public class MappingModelCreationHelper {
if ( bootMapKeyDescriptor instanceof BasicValue ) {
final BasicValue basicValue = (BasicValue) bootMapKeyDescriptor;
final Selectable selectable = basicValue.getColumnIterator().next();
final SelectionMapping selectionMapping = SelectionMappingImpl.from(
tableExpression,
basicValue.getColumnIterator().next(),
basicValue.resolve().getJdbcMapping(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
return new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.INDEX,
basicValue.resolve().getJdbcMapping(),
basicValue.resolve().getValueConverter(),
tableExpression,
selectable.getText( dialect ),
selectable.getCustomReadExpression(),
selectable.getCustomWriteExpression()
selectionMapping
);
}
@ -1132,19 +1176,6 @@ public class MappingModelCreationHelper {
final Component component = (Component) bootMapKeyDescriptor;
final CompositeType compositeType = (CompositeType) component.getType();
final List<String> columnExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final List<String> customReadExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final List<String> customWriteExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final Iterator<Selectable> selectableItr = component.getColumnIterator();
while ( selectableItr.hasNext() ) {
final Selectable selectable = selectableItr.next();
columnExpressions.add( selectable.getText( dialect ) );
customReadExpressions.add( selectable.getCustomReadExpression() );
customWriteExpressions.add( selectable.getCustomWriteExpression() );
}
final EmbeddableMappingType mappingType = EmbeddableMappingType.from(
component,
@ -1156,9 +1187,6 @@ public class MappingModelCreationHelper {
// parent-injection
component.getParentProperty(),
tableExpression,
columnExpressions,
customReadExpressions,
customWriteExpressions,
sqlAliasStem
),
creationProcess
@ -1220,16 +1248,18 @@ public class MappingModelCreationHelper {
if ( element instanceof BasicValue ) {
final BasicValue basicElement = (BasicValue) element;
final Selectable selectable = basicElement.getColumnIterator().next();
final SelectionMapping selectionMapping = SelectionMappingImpl.from(
tableExpression,
basicElement.getColumnIterator().next(),
basicElement.resolve().getJdbcMapping(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
return new BasicValuedCollectionPart(
collectionDescriptor,
CollectionPart.Nature.ELEMENT,
basicElement.resolve().getJdbcMapping(),
basicElement.resolve().getValueConverter(),
tableExpression,
selectable.getText( dialect ),
selectable.getCustomReadExpression(),
selectable.getCustomWriteExpression()
selectionMapping
);
}
@ -1237,18 +1267,6 @@ public class MappingModelCreationHelper {
final Component component = (Component) element;
final CompositeType compositeType = (CompositeType) collectionDescriptor.getElementType();
final List<String> columnExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final List<String> customReadExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final List<String> customWriteExpressions = CollectionHelper.arrayList( component.getColumnSpan() );
final Iterator<Selectable> selectableItr = component.getColumnIterator();
while ( selectableItr.hasNext() ) {
final Selectable selectable = selectableItr.next();
columnExpressions.add( selectable.getText( dialect ) );
customReadExpressions.add( selectable.getCustomWriteExpression() );
customWriteExpressions.add( selectable.getCustomWriteExpression() );
}
final EmbeddableMappingType mappingType = EmbeddableMappingType.from(
component,
@ -1260,9 +1278,6 @@ public class MappingModelCreationHelper {
// parent-injection
component.getParentProperty(),
tableExpression,
columnExpressions,
customReadExpressions,
customWriteExpressions,
sqlAliasStem
),
creationProcess

View File

@ -14,7 +14,6 @@ import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.Property;
@ -24,7 +23,6 @@ import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.ComponentType;
/**
@ -47,7 +45,6 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
List<SingularAttributeMapping> idAttributeMappings,
StateArrayContributorMetadataAccess attributeMetadataAccess,
String rootTableName,
String[] rootTableKeyColumnNames,
Component bootIdClassDescriptor,
Component bootCidDescriptor,
MappingModelCreationProcess creationProcess) {
@ -57,7 +54,6 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
embeddableDescriptor,
entityMapping,
rootTableName,
rootTableKeyColumnNames,
creationProcess.getCreationContext().getSessionFactory()
);
@ -72,7 +68,7 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
}
@Override
public Collection<SingularAttributeMapping> getAttributes() {
public List<SingularAttributeMapping> getAttributes() {
return idAttributeMappings;
}
@ -87,10 +83,8 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
final SessionFactoryImplementor factory = session.getFactory();
final Object[] propertyValues = ( (ComponentType) bootIdClassDescriptor.getType() )
.getPropertyValues( id, session );
final MutableInteger index = new MutableInteger();
getAttributes().forEach(
attribute -> {
final int position = index.getAndIncrement();
forEachAttribute(
(position, attribute) -> {
Object propertyValue = propertyValues[position];
final Property property = bootIdClassDescriptor.getProperty( position );
if ( attribute instanceof ToOneAttributeMapping && !( property.getValue() instanceof ManyToOne ) ) {

View File

@ -22,6 +22,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.IndexedCollection;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.List;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
@ -29,6 +30,7 @@ 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.SelectionMapping;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
@ -46,7 +48,6 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.FromClauseAccess;
import org.hibernate.sql.ast.spi.SqlAliasBase;
@ -71,7 +72,6 @@ import org.hibernate.sql.results.graph.collection.internal.DelayedCollectionFetc
import org.hibernate.sql.results.graph.collection.internal.EagerCollectionFetch;
import org.hibernate.sql.results.graph.collection.internal.SelectEagerCollectionFetch;
import org.hibernate.type.EntityType;
import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
@ -326,12 +326,16 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
if ( fkTargetPart instanceof BasicValuedModelPart ) {
final BasicValuedModelPart basicFkTargetPart = (BasicValuedModelPart) fkTargetPart;
final Joinable collectionDescriptorAsJoinable = (Joinable) collectionDescriptor;
return new SimpleForeignKeyDescriptor(
final SelectionMapping keySelectionMapping = SelectionMappingImpl.from(
collectionDescriptorAsJoinable.getTableName(),
fkBootDescriptorSource.getColumnIterator().next().getText( dialect ),
basicFkTargetPart.getContainingTableExpression(),
basicFkTargetPart.getMappedColumnExpression(),
basicFkTargetPart.getJdbcMapping()
fkBootDescriptorSource.getColumnIterator().next(),
basicFkTargetPart.getJdbcMapping(),
dialect,
creationProcess.getSqmFunctionRegistry()
);
return new SimpleForeignKeyDescriptor(
keySelectionMapping,
basicFkTargetPart
);
}
else if ( fkTargetPart instanceof EmbeddableValuedModelPart ) {
@ -993,12 +997,21 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
elementDescriptor.visitJdbcTypes( action, clause, typeConfiguration );
public int getJdbcTypeCount() {
int span = elementDescriptor.getJdbcTypeCount();
if ( indexDescriptor != null ) {
indexDescriptor.visitJdbcTypes( action, clause, typeConfiguration );
span += indexDescriptor.getJdbcTypeCount();
}
return span;
}
@Override
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
int span = elementDescriptor.forEachJdbcType( offset, action );
if ( indexDescriptor != null ) {
span += indexDescriptor.forEachJdbcType( offset + span, action );
}
return span;
}
@Override

View File

@ -0,0 +1,95 @@
/*
* 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 org.hibernate.dialect.Dialect;
import org.hibernate.mapping.Selectable;
import org.hibernate.metamodel.mapping.SelectionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
/**
* @author Christian Beikov
*/
public class SelectionMappingImpl implements SelectionMapping {
private final String containingTableExpression;
private final String selectionExpression;
private final String customReadExpression;
private final String customWriteExpression;
private final boolean isFormula;
private final JdbcMapping jdbcMapping;
private SelectionMappingImpl(
String containingTableExpression,
String selectionExpression,
String customReadExpression,
String customWriteExpression,
boolean isFormula,
JdbcMapping jdbcMapping) {
// Save memory by using interned strings. Probability is high that we have multiple duplicate strings
this.containingTableExpression = containingTableExpression == null ? null : containingTableExpression.intern();
this.selectionExpression = selectionExpression == null ? null : selectionExpression.intern();
this.customReadExpression = customReadExpression == null ? null : customReadExpression.intern();
this.customWriteExpression = customWriteExpression == null ? null : customWriteExpression.intern();
this.isFormula = isFormula;
this.jdbcMapping = jdbcMapping;
}
public static SelectionMapping from(
final String containingTableExpression,
final Selectable selectable,
final JdbcMapping jdbcMapping,
final Dialect dialect,
final SqmFunctionRegistry sqmFunctionRegistry) {
final String columnExpression;
if ( selectable.isFormula() ) {
columnExpression = selectable.getTemplate( dialect, sqmFunctionRegistry );
}
else {
columnExpression = selectable.getText( dialect );
}
return new SelectionMappingImpl(
containingTableExpression,
columnExpression,
selectable.getCustomReadExpression(),
selectable.getCustomWriteExpression(),
selectable.isFormula(),
jdbcMapping
);
}
@Override
public String getContainingTableExpression() {
return containingTableExpression;
}
@Override
public String getSelectionExpression() {
return selectionExpression;
}
@Override
public String getCustomReadExpression() {
return customReadExpression;
}
@Override
public String getCustomWriteExpression() {
return customWriteExpression;
}
@Override
public boolean isFormula() {
return isFormula;
}
@Override
public JdbcMapping getJdbcMapping() {
return jdbcMapping;
}
}

View File

@ -0,0 +1,120 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.metamodel.mapping.internal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.Selectable;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.SelectionMapping;
import org.hibernate.metamodel.mapping.SelectionMappings;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.CompositeType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
/**
* @author Christian Beikov
*/
public class SelectionMappingsImpl implements SelectionMappings {
private final SelectionMapping[] selectionMappings;
private SelectionMappingsImpl(SelectionMapping[] selectionMappings) {
this.selectionMappings = selectionMappings;
}
private static void resolveJdbcMappings(List<JdbcMapping> jdbcMappings, Mapping mapping, Type valueType) {
final Type keyType;
if ( valueType instanceof EntityType ) {
keyType = ( (EntityType) valueType ).getIdentifierOrUniqueKeyType( mapping );
}
else {
keyType = valueType;
}
if ( keyType instanceof CompositeType ) {
Type[] subtypes = ( (CompositeType) keyType ).getSubtypes();
for ( Type subtype : subtypes ) {
resolveJdbcMappings( jdbcMappings, mapping, subtype );
}
}
else {
jdbcMappings.add( (JdbcMapping) keyType );
}
}
public static SelectionMappings from(
String containingTableExpression,
Value value,
Mapping mapping,
Dialect dialect,
SqmFunctionRegistry sqmFunctionRegistry) {
final List<JdbcMapping> jdbcMappings = new ArrayList<>();
resolveJdbcMappings( jdbcMappings, mapping, value.getType() );
final List<SelectionMapping> selectionMappings = new ArrayList<>( jdbcMappings.size() );
final Iterator<Selectable> columnIterator = value.getColumnIterator();
while ( columnIterator.hasNext() ) {
final Selectable selectable = columnIterator.next();
selectionMappings.add(
SelectionMappingImpl.from(
containingTableExpression,
selectable,
jdbcMappings.get( selectionMappings.size() ),
dialect,
sqmFunctionRegistry
)
);
}
return new SelectionMappingsImpl( selectionMappings.toArray( new SelectionMapping[0] ) );
}
public static SelectionMappings from(EmbeddableMappingType embeddableMappingType) {
final int propertySpan = embeddableMappingType.getNumberOfAttributeMappings();
final List<SelectionMapping> selectionMappings = CollectionHelper.arrayList( propertySpan );
embeddableMappingType.forEachAttributeMapping(
(index, attributeMapping) -> {
attributeMapping.forEachSelection(
(columnIndex, selection) -> {
selectionMappings.add( selection );
}
);
}
);
return new SelectionMappingsImpl( selectionMappings.toArray( new SelectionMapping[0] ) );
}
@Override
public SelectionMapping getSelectionMapping(int columnIndex) {
return selectionMappings[columnIndex];
}
@Override
public int getJdbcTypeCount() {
return selectionMappings.length;
}
@Override
public int forEachSelection(final int offset, final SelectionConsumer consumer) {
for ( int i = 0; i < selectionMappings.length; i++ ) {
consumer.accept( offset + i, selectionMappings[i] );
}
return selectionMappings.length;
}
}

View File

@ -8,15 +8,16 @@ package org.hibernate.metamodel.mapping.internal;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.AssociationKey;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.SelectionMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -43,30 +44,20 @@ import org.hibernate.sql.results.graph.FetchOptions;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.basic.BasicResult;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicValuedModelPart, FetchOptions {
private final String keyColumnContainingTable;
private final String keyColumnExpression;
private final String targetColumnContainingTable;
private final String targetColumnExpression;
private final JdbcMapping jdbcMapping;
private final SelectionMapping keySelectionMapping;
private final SelectionMapping targetSelectionMapping;
private AssociationKey associationKey;
public SimpleForeignKeyDescriptor(
String keyColumnContainingTable,
String keyColumnExpression,
String targetColumnContainingTable,
String targetColumnExpression,
JdbcMapping jdbcMapping) {
this.keyColumnContainingTable = keyColumnContainingTable;
this.keyColumnExpression = keyColumnExpression;
this.targetColumnContainingTable = targetColumnContainingTable;
this.targetColumnExpression = targetColumnExpression;
this.jdbcMapping = jdbcMapping;
SelectionMapping keySelectionMapping,
SelectionMapping targetSelectionMapping) {
this.keySelectionMapping = keySelectionMapping;
this.targetSelectionMapping = targetSelectionMapping;
}
@Override
@ -74,31 +65,27 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
NavigablePath collectionPath,
TableGroup tableGroup,
DomainResultCreationState creationState) {
if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) {
if ( targetSelectionMapping.getContainingTableExpression().equals( keySelectionMapping.getContainingTableExpression() ) ) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
final TableReference tableReference = tableGroup.resolveTableReference( keySelectionMapping.getContainingTableExpression() );
final String identificationVariable = tableReference.getIdentificationVariable();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
targetColumnExpression
targetSelectionMapping.getSelectionExpression()
),
s ->
new ColumnReference(
identificationVariable,
targetColumnExpression,
false,
null,
null,
jdbcMapping,
targetSelectionMapping,
creationState.getSqlAstCreationState()
.getCreationContext()
.getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
targetSelectionMapping.getJdbcMapping().getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
);
@ -106,7 +93,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return new BasicResult<Object>(
sqlSelection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
targetSelectionMapping.getJdbcMapping().getJavaTypeDescriptor()
);
}
else {
@ -130,26 +117,22 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
DomainResultCreationState creationState) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
final TableReference tableReference = tableGroup.resolveTableReference( keySelectionMapping.getContainingTableExpression() );
final String identificationVariable = tableReference.getIdentificationVariable();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
keyColumnExpression
keySelectionMapping.getSelectionExpression()
),
s ->
new ColumnReference(
identificationVariable,
keyColumnExpression,
false,
null,
null,
jdbcMapping,
keySelectionMapping,
creationState.getSqlAstCreationState().getCreationContext().getSessionFactory()
)
),
jdbcMapping.getJavaTypeDescriptor(),
keySelectionMapping.getJdbcMapping().getJavaTypeDescriptor(),
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
);
@ -157,7 +140,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return new BasicResult(
sqlSelection.getValuesArrayPosition(),
null,
jdbcMapping.getJavaTypeDescriptor()
keySelectionMapping.getJdbcMapping().getJavaTypeDescriptor()
);
}
@ -168,25 +151,17 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
SqlAstJoinType sqlAstJoinType,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
if ( lhs.getTableReference( keyColumnContainingTable ) != null ) {
if ( lhs.getTableReference( keySelectionMapping.getContainingTableExpression() ) != null ) {
return new ComparisonPredicate(
new ColumnReference(
lhs,
keyColumnExpression,
false,
null,
null,
jdbcMapping,
keySelectionMapping,
creationContext.getSessionFactory()
),
ComparisonOperator.EQUAL,
new ColumnReference(
rhs,
targetColumnExpression,
false,
null,
null,
jdbcMapping,
targetSelectionMapping,
creationContext.getSessionFactory()
)
);
@ -195,21 +170,13 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
return new ComparisonPredicate(
new ColumnReference(
lhs,
targetColumnExpression,
false,
null,
null,
jdbcMapping,
targetSelectionMapping,
creationContext.getSessionFactory()
),
ComparisonOperator.EQUAL,
new ColumnReference(
rhs,
keyColumnExpression,
false,
null,
null,
jdbcMapping,
keySelectionMapping,
creationContext.getSessionFactory()
)
);
@ -225,22 +192,22 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
SqlAstCreationContext creationContext) {
TableReference lhsTableReference;
TableReference rhsTableKeyReference;
if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) {
lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keyColumnContainingTable );
if ( targetSelectionMapping.getContainingTableExpression().equals( keySelectionMapping.getContainingTableExpression() ) ) {
lhsTableReference = getTableReferenceWhenTargetEqualsKey( lhs, tableGroup, keySelectionMapping.getContainingTableExpression() );
rhsTableKeyReference = getTableReference(
lhs,
tableGroup,
targetColumnContainingTable
targetSelectionMapping.getContainingTableExpression()
);
}
else {
lhsTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable );
lhsTableReference = getTableReference( lhs, tableGroup, keySelectionMapping.getContainingTableExpression() );
rhsTableKeyReference = getTableReference(
lhs,
tableGroup,
targetColumnContainingTable
targetSelectionMapping.getContainingTableExpression()
);
}
@ -288,7 +255,7 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
@Override
public JavaTypeDescriptor<?> getJavaTypeDescriptor() {
return jdbcMapping.getJavaTypeDescriptor();
return targetSelectionMapping.getJdbcMapping().getJavaTypeDescriptor();
}
@Override
@ -302,84 +269,72 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
}
@Override
public void visitReferringColumns(ColumnConsumer consumer) {
consumer.accept(
keyColumnContainingTable,
keyColumnExpression,
false,
null,
null,
jdbcMapping
);
public int visitReferringColumns(int offset, SelectionConsumer consumer) {
consumer.accept( offset, keySelectionMapping );
return getJdbcTypeCount();
}
@Override
public void visitTargetColumns(ColumnConsumer consumer) {
consumer.accept(
targetColumnContainingTable,
targetColumnExpression,
false,
null,
null,
jdbcMapping
);
public int visitTargetColumns(int offset, SelectionConsumer consumer) {
consumer.accept( offset, targetSelectionMapping );
return getJdbcTypeCount();
}
@Override
public AssociationKey getAssociationKey() {
if ( associationKey == null ) {
final List<String> associationKeyColumns = Collections.singletonList( keyColumnExpression );
associationKey = new AssociationKey( keyColumnContainingTable, associationKeyColumns );
final List<String> associationKeyColumns = Collections.singletonList( keySelectionMapping.getSelectionExpression() );
associationKey = new AssociationKey( keySelectionMapping.getContainingTableExpression(), associationKeyColumns );
}
return associationKey;
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return 1;
public List<JdbcMapping> getJdbcMappings() {
return Collections.singletonList( targetSelectionMapping.getJdbcMapping() );
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
return Collections.singletonList( jdbcMapping );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
action.accept( offset, targetSelectionMapping.getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
action.accept( jdbcMapping );
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
valuesConsumer.consume( value, jdbcMapping );
valuesConsumer.consume( offset, value, targetSelectionMapping.getJdbcMapping() );
return getJdbcTypeCount();
}
@Override
public String getContainingTableExpression() {
return keyColumnContainingTable;
return keySelectionMapping.getContainingTableExpression();
}
@Override
public String getMappedColumnExpression() {
return keyColumnExpression;
public String getSelectionExpression() {
return keySelectionMapping.getSelectionExpression();
}
@Override
public boolean isFormula() {
return keySelectionMapping.isFormula();
}
@Override
public String getCustomReadExpression() {
return null;
return keySelectionMapping.getCustomReadExpression();
}
@Override
public String getCustomWriteExpression() {
return null;
return keySelectionMapping.getCustomWriteExpression();
}
@Override
@ -421,12 +376,13 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor, BasicVa
@Override
public JdbcMapping getJdbcMapping() {
return jdbcMapping;
return keySelectionMapping.getJdbcMapping();
}
@Override
public String toString() {
return "SimpleForeignKeyDescriptor : " + keyColumnContainingTable + "." + keyColumnExpression
+ " --> " + targetColumnContainingTable + "." + targetColumnExpression;
return "SimpleForeignKeyDescriptor : " + keySelectionMapping.getContainingTableExpression() + "." + keySelectionMapping
.getSelectionExpression()
+ " --> " + targetSelectionMapping.getContainingTableExpression() + "." + targetSelectionMapping.getSelectionExpression();
}
}

View File

@ -10,7 +10,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.loader.NaturalIdPostLoadListener;
@ -19,7 +18,8 @@ import org.hibernate.loader.ast.internal.MultiNaturalIdLoaderStandard;
import org.hibernate.loader.ast.internal.SimpleNaturalIdLoader;
import org.hibernate.loader.ast.spi.MultiNaturalIdLoader;
import org.hibernate.loader.ast.spi.NaturalIdLoader;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingType;
@ -31,7 +31,6 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Single-attribute NaturalIdMapping implementation
@ -136,23 +135,23 @@ public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping {
}
@Override
public void visitColumns(ColumnConsumer consumer) {
attribute.visitColumns( consumer );
public int forEachSelection(int offset, SelectionConsumer consumer) {
return attribute.forEachSelection( offset, consumer );
}
@Override
public int getJdbcTypeCount(TypeConfiguration typeConfiguration) {
return attribute.getJdbcTypeCount( typeConfiguration );
public int getJdbcTypeCount() {
return attribute.getJdbcTypeCount();
}
@Override
public List<JdbcMapping> getJdbcMappings(TypeConfiguration typeConfiguration) {
return attribute.getJdbcMappings( typeConfiguration );
public List<JdbcMapping> getJdbcMappings() {
return attribute.getJdbcMappings();
}
@Override
public void visitJdbcTypes(Consumer<JdbcMapping> action, Clause clause, TypeConfiguration typeConfiguration) {
attribute.visitJdbcTypes( action, clause, typeConfiguration );
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
return attribute.forEachJdbcType( offset, action );
}
@Override
@ -161,12 +160,22 @@ public class SimpleNaturalIdMapping extends AbstractNaturalIdMapping {
}
@Override
public void visitDisassembledJdbcValues(Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
attribute.visitDisassembledJdbcValues( value, clause, valuesConsumer, session );
public int forEachDisassembledJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return attribute.forEachDisassembledJdbcValue( value, clause, offset, valuesConsumer, session );
}
@Override
public void visitJdbcValues(Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
attribute.visitJdbcValues( value, clause, valuesConsumer, session );
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
return attribute.forEachJdbcValue( value, clause, offset, valuesConsumer, session );
}
}

View File

@ -14,7 +14,7 @@ import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.OneToOne;
import org.hibernate.mapping.ToOne;
import org.hibernate.metamodel.mapping.AssociationKey;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityAssociationMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
@ -618,9 +618,12 @@ public class ToOneAttributeMapping extends AbstractSingularAttributeMapping
}
@Override
public void visitColumns(ColumnConsumer consumer) {
public int forEachSelection(int offset, SelectionConsumer consumer) {
if ( isKeyReferringSide ) {
foreignKeyDescriptor.visitReferringColumns( consumer );
return foreignKeyDescriptor.visitReferringColumns( offset, consumer );
}
else {
return 0;
}
}
}

View File

@ -11,17 +11,22 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
@ -31,7 +36,6 @@ import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Standard Hibernate implementation of JPA's {@link javax.persistence.metamodel.EmbeddableType}
@ -88,39 +92,52 @@ public class EmbeddableTypeImpl<J>
}
@Override
public void visitJdbcValues(
Object value, Clause clause, JdbcValuesConsumer valuesConsumer, SharedSessionContractImplementor session) {
Object[] disassemble = (Object[]) disassemble( value, session );
List<JdbcMapping> jdbcMappings = getJdbcMappings( session.getFactory().getTypeConfiguration() );
for ( int i = 0; i < disassemble.length; i++ ) {
valuesConsumer.consume( disassemble[i], jdbcMappings.get( i ) );
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer valuesConsumer,
SharedSessionContractImplementor session) {
final Object[] disassemble = (Object[]) disassemble( value, session );
return forEachJdbcType(
(i, jdbcMapping) -> {
valuesConsumer.consume( i + offset, disassemble[i], jdbcMapping );
}
);
}
@Override
public void visitJdbcTypes(
Consumer<JdbcMapping> action,
Clause clause,
TypeConfiguration typeConfiguration) {
Set<Attribute<? super J, ?>> attributes = getAttributes();
for ( Attribute attribute : attributes ) {
if ( attribute instanceof SingularAttributeImpl ) {
if ( attribute.isAssociation() ) {
EntityTypeImpl entityType = (EntityTypeImpl) ( (SingularAttributeImpl) attribute ).getValueGraphType();
BasicType basicType = jpaMetamodel().getTypeConfiguration()
.getBasicTypeForJavaType( entityType.findIdAttribute().getJavaType() );
action.accept( basicType.getJdbcMapping() );
}
else {
BasicType basicType = jpaMetamodel().getTypeConfiguration()
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
final MappingMetamodel metamodel = jpaMetamodel().getTypeConfiguration().getSessionFactory().getMetamodel();
int i = 0;
for ( Attribute<? super J, ?> attribute : getAttributes() ) {
if ( attribute instanceof SingularAttribute<?, ?> ) {
Type<?> type = ( (SingularAttribute<? super J, ?>) attribute ).getType();
switch ( type.getPersistenceType() ) {
case BASIC:
BasicType<?> basicType = jpaMetamodel().getTypeConfiguration()
.getBasicTypeForJavaType( attribute.getJavaType() );
action.accept( basicType.getJdbcMapping() );
action.accept( i + offset, basicType.getJdbcMapping() );
i++;
break;
case ENTITY:
final EntityPersister entityDescriptor = metamodel.getEntityDescriptor(
( (EntityDomainType<?>) type ).getHibernateEntityName()
);
i += entityDescriptor.getEntityMappingType().getIdentifierMapping().forEachJdbcType(
i + offset,
action
);
break;
case EMBEDDABLE:
i += ( (Bindable) type ).forEachJdbcType( i + offset, action );
break;
default:
throw new IllegalArgumentException( "Unsupported type: " + type );
}
}
}
return i;
}
@Override

View File

@ -131,6 +131,7 @@ import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue;
import org.hibernate.mapping.IndexedConsumer;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
@ -143,22 +144,21 @@ import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.AttributeMapping;
import org.hibernate.metamodel.mapping.AttributeMetadata;
import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.EntityRowIdMapping;
import org.hibernate.metamodel.mapping.EntityVersionMapping;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.mapping.NaturalIdMapping;
import org.hibernate.metamodel.mapping.Queryable;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
import org.hibernate.metamodel.mapping.internal.EntityRowIdMappingImpl;
@ -1386,14 +1386,10 @@ public abstract class AbstractEntityPersister
final String[] fkColumnNames = getSubclassTableKeyColumns( subClassTablePosition );
assert rootPkColumnNames.length == fkColumnNames.length;
assert rootPkColumnNames.length == identifierMapping.getJdbcTypeCount( factory.getTypeConfiguration() );
assert rootPkColumnNames.length == identifierMapping.getJdbcTypeCount();
identifierMapping.visitJdbcTypes(
new Consumer<JdbcMapping>() {
private int columnIndex;
@Override
public void accept(JdbcMapping jdbcMapping) {
identifierMapping.forEachSelection(
(columnIndex, selection) -> {
final String rootPkColumnName = rootPkColumnNames[ columnIndex ];
final Expression pkColumnExpression = sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
@ -1402,11 +1398,7 @@ public abstract class AbstractEntityPersister
),
sqlAstProcessingState -> new ColumnReference(
rootTableReference.getIdentificationVariable(),
rootPkColumnName,
false,
null,
null,
jdbcMapping,
selection,
getFactory()
)
);
@ -1423,18 +1415,13 @@ public abstract class AbstractEntityPersister
false,
null,
null,
jdbcMapping,
selection.getJdbcMapping(),
getFactory()
)
);
conjunction.add( new ComparisonPredicate( pkColumnExpression, ComparisonOperator.EQUAL, fkColumnExpression ) );
columnIndex++;
}
},
Clause.IRRELEVANT,
getFactory().getTypeConfiguration()
);
return conjunction;
@ -5858,6 +5845,13 @@ public abstract class AbstractEntityPersister
attributeMappings.forEach( action );
}
@Override
public void forEachAttributeMapping(IndexedConsumer<AttributeMapping> consumer) {
for ( int i = 0; i < attributeMappings.size(); i++ ) {
consumer.accept( i, attributeMappings.get( i ) );
}
}
@Override
public void prepareMappingModel(MappingModelCreationProcess creationProcess) {
if ( identifierMapping != null ) {
@ -6083,10 +6077,18 @@ public abstract class AbstractEntityPersister
return null;
}
else {
final String discriminatorColumnExpression;
if ( getDiscriminatorFormulaTemplate() == null ) {
discriminatorColumnExpression = getDiscriminatorColumnReaders();
}
else {
discriminatorColumnExpression = getDiscriminatorFormulaTemplate();
}
return new EntityDiscriminatorMappingImpl(
this,
getTableName(),
getDiscriminatorColumnReaders(),
discriminatorColumnExpression,
getDiscriminatorFormulaTemplate() != null,
(BasicType) getDiscriminatorType()
);
}
@ -6252,17 +6254,18 @@ public abstract class AbstractEntityPersister
final BasicValue bootModelVersionValue = (BasicValue) bootModelRootEntityDescriptor.getVersion().getValue();
final BasicValue.Resolution<?> basicTypeResolution = bootModelVersionValue.resolve();
final Iterator versionColumnIterator = bootModelRootEntityDescriptor.getVersion().getColumnIterator();
final Iterator<Selectable> versionColumnIterator = bootModelRootEntityDescriptor.getVersion().getColumnIterator();
assert versionColumnIterator.hasNext();
final Dialect dialect = creationProcess.getCreationContext().getSessionFactory().getJdbcServices().getDialect();
final String versionColumnName = ( (Column) versionColumnIterator.next() ).getQuotedName( dialect );
final Selectable column = versionColumnIterator.next();
assert !versionColumnIterator.hasNext();
assert !column.isFormula();
return new EntityVersionMappingImpl(
bootModelRootEntityDescriptor.getVersion().getName(),
entityPersister.getTableName(),
versionColumnName,
column.getText( dialect ),
basicTypeResolution.getLegacyResolvedBasicType(),
entityPersister
);
@ -6283,8 +6286,6 @@ public abstract class AbstractEntityPersister
final String tableExpression = getPropertyTableName( attrName );
final String[] attrColumnNames = getPropertyColumnNames( propertyIndex );
final String[] customReadExprs = getSubclassPropertyColumnReaderClosure()[ propertyIndex ];
final String[] customWriteExprs = getPropertyColumnWriters( propertyIndex );
final PropertyAccess propertyAccess = getRepresentationStrategy().resolvePropertyAccess( bootProperty );
@ -6435,9 +6436,7 @@ public abstract class AbstractEntityPersister
this,
(CompositeType) attrType,
tableExpression,
attrColumnNames,
customReadExprs,
customWriteExprs,
null,
propertyAccess,
tupleAttrDefinition.getCascadeStyle(),
creationProcess
@ -6510,7 +6509,7 @@ public abstract class AbstractEntityPersister
}
@Override
public Collection<AttributeMapping> getAttributeMappings() {
public List<AttributeMapping> getAttributeMappings() {
if ( attributeMappings == null ) {
attributeMappings = new ArrayList<>();
@ -6695,10 +6694,13 @@ public abstract class AbstractEntityPersister
}
@Override
public void visitColumns(ColumnConsumer consumer) {
getAttributeMappings().forEach(
attributeMapping -> attributeMapping.visitColumns( consumer )
);
public int forEachSelection(int offset, SelectionConsumer selectionConsumer) {
int span = 0;
final List<AttributeMapping> mappings = getAttributeMappings();
for ( int i = 0; i < mappings.size(); i++ ) {
span += mappings.get( i ).forEachSelection( span + offset, selectionConsumer );
}
return span;
}
@Override
@ -6729,15 +6731,19 @@ public abstract class AbstractEntityPersister
}
@Override
public void visitJdbcValues(
public int forEachJdbcValue(
Object value,
Clause clause,
int offset,
JdbcValuesConsumer consumer,
SharedSessionContractImplementor session) {
getAttributeMappings().forEach(
attributeMapping ->
attributeMapping.visitJdbcValues( value, clause, consumer, session )
);
int span = 0;
final List<AttributeMapping> mappings = getAttributeMappings();
for ( int i = 0; i < mappings.size(); i++ ) {
final AttributeMapping attributeMapping = mappings.get( i );
span += attributeMapping.forEachJdbcValue( value, clause, span + offset, consumer, session );
}
return span;
}
@Override

View File

@ -33,7 +33,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.DynamicFilterAliasGenerator;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.util.MarkerObject;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
@ -1386,11 +1385,19 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
public EntityDiscriminatorMapping getDiscriminatorMapping(TableGroup tableGroup) {
if ( hasSubclasses() ) {
if ( explicitDiscriminatorColumnName == null ) {
final String discriminatorColumnExpression;
if ( getDiscriminatorFormulaTemplate() == null ) {
discriminatorColumnExpression = getDiscriminatorColumnName();
}
else {
discriminatorColumnExpression = getDiscriminatorFormulaTemplate();
}
CaseSearchedExpressionInfo info = getCaseSearchedExpression( tableGroup );
return new JoinedSubclassDiscriminatorMappingImpl(
this,
getTableName(),
getDiscriminatorColumnName(),
discriminatorColumnExpression,
getDiscriminatorFormulaTemplate() != null,
info.caseSearchedExpression,
info.columnReferences,
(BasicType) getDiscriminatorType()
@ -1405,25 +1412,14 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
@Override
public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {
final MutableInteger tablePositionWrapper = new MutableInteger();
for ( String tableName : constraintOrderedTableNames ) {
final int tablePosition = tablePositionWrapper.getAndIncrement();
for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {
final String tableName = constraintOrderedTableNames[i];
final int tablePosition = i;
consumer.consume(
tableName,
() -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) {
columnConsumer.accept(
tableName,
column,
false,
null,
null,
null
);
}
columnConsumer.accept(tableName, constraintOrderedKeyColumnNames[tablePosition]);
}
);
}
@ -1493,7 +1489,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
}
private ColumnReference getIdentifierColumnReference(TableReference tableReference) {
final List<JdbcMapping> jdbcMappings = getIdentifierMapping().getJdbcMappings( getFactory().getTypeConfiguration() );
final List<JdbcMapping> jdbcMappings = getIdentifierMapping().getJdbcMappings();
return new ColumnReference(
tableReference.getIdentificationVariable(),
discriminatorColumnNameByTableName.get( tableReference.getTableExpression() ),

View File

@ -934,13 +934,29 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
TableGroup tableGroup,
SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) {
final String columnReferenceKey;
final String discriminatorExpression;
if ( isDiscriminatorFormula() ) {
discriminatorExpression = getDiscriminatorFormulaTemplate();
columnReferenceKey = SqlExpressionResolver.createColumnReferenceKey(
tableGroup.getPrimaryTableReference(),
getDiscriminatorFormulaTemplate()
);
}
else {
discriminatorExpression = getDiscriminatorColumnName();
columnReferenceKey = SqlExpressionResolver.createColumnReferenceKey(
tableGroup.getPrimaryTableReference(),
getDiscriminatorColumnName()
);
}
return new ComparisonPredicate(
sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableGroup.getPrimaryTableReference(), getDiscriminatorColumnName() ),
columnReferenceKey,
sqlAstProcessingState -> new ColumnReference(
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
getDiscriminatorColumnName(),
false,
discriminatorExpression,
isDiscriminatorFormula(),
null,
null,
( (BasicType<?>) getDiscriminatorType() ).getJdbcMapping(),
@ -957,25 +973,14 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
@Override
public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {
final MutableInteger tablePositionWrapper = new MutableInteger();
for ( String tableName : constraintOrderedTableNames ) {
final int tablePosition = tablePositionWrapper.getAndIncrement();
for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {
final String tableName = constraintOrderedTableNames[i];
final int tablePosition = i;
consumer.consume(
tableName,
() -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) {
columnConsumer.accept(
tableName,
column,
false,
null,
null,
null
);
}
columnConsumer.accept(tableName, constraintOrderedKeyColumnNames[tablePosition]);
}
);
}

View File

@ -380,25 +380,14 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
@Override
public void visitConstraintOrderedTables(ConstraintOrderedTableConsumer consumer) {
final MutableInteger tablePositionWrapper = new MutableInteger();
for ( String tableName : constraintOrderedTableNames ) {
final int tablePosition = tablePositionWrapper.getAndIncrement();
for ( int i = 0; i < constraintOrderedTableNames.length; i++ ) {
final String tableName = constraintOrderedTableNames[i];
final int tablePosition = i;
consumer.consume(
tableName,
() -> columnConsumer -> {
final String[] keyColumnNames = constraintOrderedKeyColumnNames[tablePosition];
for ( String column : keyColumnNames ) {
columnConsumer.accept(
tableName,
column,
false,
null,
null,
null
);
}
columnConsumer.accept(tableName, constraintOrderedKeyColumnNames[tablePosition]);
}
);
}

View File

@ -65,7 +65,7 @@ public class CompleteFetchBuilderBasicPart implements CompleteFetchBuilder, Mode
final DomainResultCreationStateImpl creationState = impl( domainResultCreationState );
final String mappedTable = referencedModelPart.getContainingTableExpression();
final String mappedColumn = referencedModelPart.getMappedColumnExpression();
final String mappedColumn = referencedModelPart.getSelectionExpression();
final TableGroup tableGroup = creationState.getFromClauseAccess().getTableGroup( parent.getNavigablePath() );
final TableReference tableReference = tableGroup.getTableReference( mappedTable );

View File

@ -63,7 +63,7 @@ public class CompleteResultBuilderBasicModelPart
final TableGroup tableGroup = creationStateImpl.getFromClauseAccess().getTableGroup( navigablePath.getParent() );
final TableReference tableReference = tableGroup.getTableReference( modelPart.getContainingTableExpression() );
final String mappedColumn = modelPart.getMappedColumnExpression();
final String mappedColumn = modelPart.getSelectionExpression();
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );

View File

@ -16,17 +16,12 @@ 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.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
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.basic.BasicFetch;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.query.results.ResultsHelper.jdbcPositionToValuesArrayPosition;
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
@ -56,7 +51,7 @@ public class ImplicitFetchBuilderBasic implements ImplicitFetchBuilder {
.getFromClauseAccess()
.getTableGroup( parent.getNavigablePath() );
final String column = fetchable.getMappedColumnExpression();
final String column = fetchable.getSelectionExpression();
final String table = fetchable.getContainingTableExpression();
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( column );

View File

@ -15,7 +15,6 @@ import org.hibernate.query.results.DomainResultCreationStateImpl;
import org.hibernate.query.results.SqlSelectionImpl;
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
import org.hibernate.sql.ast.SqlAstJoinType;
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
@ -71,24 +70,24 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
}
);
fetchable.visitColumns(
(table, column, isColumnFormula, readFragment, writeFragment, jdbcMapping) -> {
final TableReference tableReference = tableGroup.getTableReference( table );
fetchable.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = tableGroup.getTableReference( selection.getContainingTableExpression() );
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( column );
final int jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( selection.getSelectionExpression() );
final int valuesArrayPosition = jdbcPositionToValuesArrayPosition( jdbcPosition );
final Expression expression = creationStateImpl.resolveSqlExpression(
createColumnReferenceKey( tableReference, column ),
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
processingState -> new SqlSelectionImpl(
valuesArrayPosition,
jdbcMapping
selection.getJdbcMapping()
)
);
creationStateImpl.resolveSqlSelection(
expression,
jdbcMapping.getJavaTypeDescriptor(),
selection.getJdbcMapping().getJavaTypeDescriptor(),
creationStateImpl.getSessionFactory().getTypeConfiguration()
);
}

View File

@ -13,7 +13,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.engine.spi.SessionFactoryImplementor;
@ -21,12 +20,10 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.mapping.Bindable;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.spi.QueryParameterBinding;
@ -44,7 +41,6 @@ import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -191,21 +187,13 @@ public class SqmUtil {
domainModel,
tableGroupLocator
);
mappingExpressable.visitJdbcTypes(
new Consumer<JdbcMapping>() {
int position = 0;
@Override
public void accept(JdbcMapping jdbcType) {
final JdbcParameter jdbcParameter = jdbcParams.get( position++ );
mappingExpressable.forEachJdbcType(
(position, jdbcType) -> {
jdbcParameterBindings.addBinding(
jdbcParameter,
jdbcParams.get( position ),
new JdbcParameterBindingImpl( jdbcType, null )
);
}
},
Clause.IRRELEVANT,
session.getFactory().getTypeConfiguration()
);
}
else if ( domainParamBinding.isMultiValued() ) {
@ -293,24 +281,14 @@ public class SqmUtil {
mappingExpressable = domainModel.resolveMappingExpressable( parameterType );
}
mappingExpressable.visitJdbcValues(
int offset = jdbcParameterBindings.registerParametersForEachJdbcValue(
bindValue,
Clause.IRRELEVANT,
new Bindable.JdbcValuesConsumer() {
private int position = 0;
@Override
public void consume(Object jdbcValue, JdbcMapping jdbcMapping) {
final JdbcParameter jdbcParameter = jdbcParams.get( position );
jdbcParameterBindings.addBinding(
jdbcParameter,
new JdbcParameterBindingImpl( jdbcMapping, jdbcValue )
);
position++;
}
},
mappingExpressable,
jdbcParams,
session
);
assert offset == jdbcParams.size();
}
public static AllowableParameterType determineParameterType(

View File

@ -14,7 +14,6 @@ import java.util.Map;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.internal.DomainParameterXref;
@ -80,20 +79,14 @@ public class MatchingIdSelectionHelper {
//noinspection rawtypes
final List<DomainResult> domainResults = new ArrayList<>();
final MutableInteger i = new MutableInteger();
targetEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
final int position = i.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
targetEntityDescriptor.getIdentifierMapping().forEachSelection(
(position, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableReference,
columnExpression,
isFormula,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);
@ -106,7 +99,7 @@ public class MatchingIdSelectionHelper {
);
//noinspection unchecked
domainResults.add( new BasicResult( position, null, jdbcMapping.getJavaTypeDescriptor() ) );
domainResults.add( new BasicResult( position, null, selection.getJdbcMapping().getJavaTypeDescriptor() ) );
}
);
@ -144,21 +137,14 @@ public class MatchingIdSelectionHelper {
final TableGroup mutatingTableGroup = sqmConverter.getMutatingTableGroup();
idSelectionQuery.getFromClause().addRoot( mutatingTableGroup );
final MutableInteger i = new MutableInteger();
targetEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
final int position = i.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
targetEntityDescriptor.getIdentifierMapping().forEachSelection(
(position, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
final Expression expression = sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableReference,
columnExpression,
// id columns cannot be formulas and cannot have custom read and write expressions
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);

View File

@ -15,7 +15,7 @@ import java.util.function.Supplier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.query.sqm.internal.DomainParameterXref;
@ -137,7 +137,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
protected void executeDelete(
QuerySpec cteDefinition,
String targetTable,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
MappingModelExpressable<?> cteType,
QuerySpec cteSubQuery,
JdbcParameterBindings jdbcParameterBindings,
@ -184,7 +184,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
protected CteStatement generateCteStatement(
QuerySpec cteDefinition,
String targetTable,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
MappingModelExpressable<?> cteType,
QuerySpec cteSubQuery,
ExecutionContext executionContext) {
@ -206,7 +206,7 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
private DeleteStatement generateCteConsumer(
String targetTable,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
MappingModelExpressable<?> cteType,
QuerySpec cteSubQuery,
ExecutionContext executionContext) {
@ -221,15 +221,11 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
final List<ColumnReference> columnsToMatchReferences = new ArrayList<>();
columnsToMatchVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, isFormula, customReadExpr, customWriteExpr, jdbcMapping) ->
(columnIndex, selection) ->
columnsToMatchReferences.add(
new ColumnReference(
targetTableReference,
columnExpression,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
sessionFactory
)
)

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.query.sqm.mutation.internal.idtable;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Supplier;
@ -17,7 +16,6 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.transaction.spi.IsolationDelegate;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
@ -89,25 +87,18 @@ public final class ExecuteWithIdTableHelper {
matchingIdSelection.getFromClause().addRoot( mutatingTableGroup );
final MutableInteger positionWrapper = new MutableInteger();
mutatingEntityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
final int jdbcPosition = positionWrapper.getAndIncrement();
final TableReference tableReference = mutatingTableGroup.resolveTableReference( containingTableExpression );
mutatingEntityDescriptor.getIdentifierMapping().forEachSelection(
(jdbcPosition, selection) -> {
final TableReference tableReference = mutatingTableGroup.resolveTableReference( selection.getContainingTableExpression() );
matchingIdSelection.getSelectClause().addSqlSelection(
new SqlSelectionImpl(
jdbcPosition,
jdbcPosition + 1,
sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
tableReference,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
factory
)
)
@ -117,7 +108,7 @@ public final class ExecuteWithIdTableHelper {
);
if ( idTable.getSessionUidColumn() != null ) {
final int jdbcPosition = positionWrapper.getAndIncrement();
final int jdbcPosition = matchingIdSelection.getSelectClause().getSqlSelections().size();
matchingIdSelection.getSelectClause().addSqlSelection(
new SqlSelectionImpl(
jdbcPosition,

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.query.sqm.mutation.internal.idtable;
import java.util.Collections;
import org.hibernate.LockMode;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.persister.entity.EntityPersister;
@ -51,17 +49,13 @@ public final class ExecuteWithoutIdTableHelper {
matchingIdSelect.getFromClause().addRoot( matchingIdSelectTableGroup );
rootEntityPersister.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
rootEntityPersister.getIdentifierMapping().forEachSelection(
(columnIndex, selection) -> {
final ColumnReference columnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( rootTableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
rootTableReference,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);

View File

@ -37,12 +37,12 @@ public class IdTable implements Exportable {
( (Joinable) entityDescriptor.getEntityPersister() ).getTableName()
);
entityDescriptor.getIdentifierMapping().visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> columns.add(
entityDescriptor.getIdentifierMapping().forEachSelection(
(columnIndex, selection) -> columns.add(
new IdTableColumn(
this,
columnExpression,
jdbcMapping
selection.getSelectionExpression(),
selection.getJdbcMapping()
)
)
);

View File

@ -23,7 +23,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.internal.FilterHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
import org.hibernate.metamodel.mapping.MappingModelHelper;
@ -263,7 +263,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
private void deleteFromNonRootTableWithoutIdTable(
TableReference targetTableReference,
Supplier<Consumer<ColumnConsumer>> tableKeyColumnVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> tableKeyColumnVisitationSupplier,
SqlExpressionResolver sqlExpressionResolver,
TableGroup rootTableGroup,
QuerySpec matchingIdSubQuerySpec,
@ -285,18 +285,14 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
*/
final List<ColumnReference> deletingTableColumnRefs = new ArrayList<>();
tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
assert targetTableReference.getTableExpression().equals( containingTableExpression );
(columnIndex, selection) -> {
assert targetTableReference.getTableExpression().equals( selection.getContainingTableExpression() );
final Expression expression = sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( targetTableReference, columnExpression ),
SqlExpressionResolver.createColumnReferenceKey( targetTableReference, selection.getSelectionExpression() ),
sqlAstProcessingState -> new ColumnReference(
rootTableGroup.getPrimaryTableReference(),
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);
@ -449,7 +445,7 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
private void deleteFromTableUsingIdTable(
String tableExpression,
Supplier<Consumer<ColumnConsumer>> tableKeyColumnVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> tableKeyColumnVisitationSupplier,
QuerySpec idTableSubQuery,
ExecutionContext executionContext) {
log.tracef( "deleteFromTableUsingIdTable - %s", tableExpression );
@ -459,20 +455,16 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor );
tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
assert containingTableExpression.equals( tableExpression );
assert ! isFormula;
assert readFragment == null;
assert writeFragment == null;
(columnIndex, selection) -> {
assert selection.getContainingTableExpression().equals( tableExpression );
assert ! selection.isFormula();
assert selection.getCustomReadExpression() == null;
assert selection.getCustomWriteExpression() == null;
keyColumnCollector.apply(
new ColumnReference(
(String) null,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
factory
)
);

View File

@ -7,7 +7,6 @@
package org.hibernate.query.sqm.mutation.internal.idtable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@ -19,7 +18,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.ModelPartContainer;
import org.hibernate.query.sqm.internal.DomainParameterXref;
@ -217,7 +216,7 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
private void updateTable(
String tableExpression,
Supplier<Consumer<ColumnConsumer>> tableKeyColumnVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> tableKeyColumnVisitationSupplier,
QuerySpec idTableSubQuery,
ExecutionContext executionContext) {
final TableReference updatingTableReference = updatingTableGroup.resolveTableReference( tableExpression );
@ -236,16 +235,12 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
final TableKeyExpressionCollector keyColumnCollector = new TableKeyExpressionCollector( entityDescriptor );
tableKeyColumnVisitationSupplier.get().accept(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
assert containingTableExpression.equals( tableExpression );
(columnIndex, selection) -> {
assert selection.getContainingTableExpression().equals( tableExpression );
keyColumnCollector.apply(
new ColumnReference(
(String) null,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);

View File

@ -13,7 +13,7 @@ import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -47,7 +47,7 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd
List<?> matchingIdValues,
EntityMappingType entityDescriptor,
TableReference mutatingTableReference,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
ExecutionContext executionContext) {
assert matchingIdValues != null;
assert ! matchingIdValues.isEmpty();
@ -55,14 +55,14 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd
final SessionFactoryImplementor sessionFactory = executionContext.getSession().getFactory();
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final int idColumnCount = identifierMapping.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int idColumnCount = identifierMapping.getJdbcTypeCount();
assert idColumnCount > 0;
final Junction predicate = new Junction( Junction.Nature.DISJUNCTION );
if ( idColumnCount == 1 ) {
final BasicValuedModelPart basicIdMapping = (BasicValuedModelPart) identifierMapping;
final String idColumn = basicIdMapping.getMappedColumnExpression();
final String idColumn = basicIdMapping.getSelectionExpression();
final ColumnReference idColumnReference = new ColumnReference(
mutatingTableReference,
idColumn,
@ -87,20 +87,16 @@ public class DisjunctionRestrictionProducer implements MatchingIdRestrictionProd
else {
final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount );
final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount );
identifierMapping.visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
identifierMapping.forEachSelection(
(columnIndex, selection) -> {
columnReferences.add(
new ColumnReference(
mutatingTableReference,
columnExpression,
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);
jdbcMappings.add( jdbcMapping );
jdbcMappings.add( selection.getJdbcMapping() );
}
);

View File

@ -13,7 +13,7 @@ import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
@ -49,7 +49,7 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
List<?> matchingIdValues,
EntityMappingType entityDescriptor,
TableReference mutatingTableReference,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
ExecutionContext executionContext) {
assert matchingIdValues != null;
assert ! matchingIdValues.isEmpty();
@ -57,14 +57,14 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
final SessionFactoryImplementor sessionFactory = executionContext.getSession().getFactory();
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final int idColumnCount = identifierMapping.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int idColumnCount = identifierMapping.getJdbcTypeCount();
assert idColumnCount > 0;
final InListPredicate predicate;
if ( idColumnCount == 1 ) {
final BasicValuedModelPart basicIdMapping = (BasicValuedModelPart) identifierMapping;
final String idColumn = basicIdMapping.getMappedColumnExpression();
final String idColumn = basicIdMapping.getSelectionExpression();
final Expression inFixture = new ColumnReference(
mutatingTableReference,
idColumn,
@ -84,21 +84,16 @@ public class InPredicateRestrictionProducer implements MatchingIdRestrictionProd
else {
final List<ColumnReference> columnReferences = new ArrayList<>( idColumnCount );
final List<JdbcMapping> jdbcMappings = new ArrayList<>( idColumnCount );
identifierMapping.visitColumns(
(containingTableExpression, columnExpression, isFormula, readFragment, writeFragment, jdbcMapping) -> {
identifierMapping.forEachSelection(
(columnIndex, selection) -> {
columnReferences.add(
new ColumnReference(
mutatingTableReference,
columnExpression,
// id columns cannot be formulas and cannot have custom read and write expressions
false,
null,
null,
jdbcMapping,
selection,
sessionFactory
)
);
jdbcMappings.add( jdbcMapping );
jdbcMappings.add( selection.getJdbcMapping() );
}
);

View File

@ -13,7 +13,7 @@ import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.FilterHelper;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.persister.entity.Joinable;
@ -141,7 +141,7 @@ public class InlineDeleteHandler implements DeleteHandler {
private void executeDelete(
String targetTableExpression,
EntityMappingType entityDescriptor,
Supplier<Consumer<ColumnConsumer>> tableKeyColumnsVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> tableKeyColumnsVisitationSupplier,
List<Object> ids,
JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext) {

View File

@ -10,7 +10,7 @@ import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.Predicate;
@ -34,6 +34,6 @@ public interface MatchingIdRestrictionProducer {
List<?> matchingIdValues,
EntityMappingType entityDescriptor,
TableReference mutatingTableReference,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
ExecutionContext executionContext);
}

View File

@ -11,7 +11,7 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.mapping.ColumnConsumer;
import org.hibernate.metamodel.mapping.SelectionConsumer;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
@ -48,7 +48,7 @@ public class TableValueConstructorRestrictionProducer implements MatchingIdRestr
List<?> matchingIdValues,
EntityMappingType entityDescriptor,
TableReference mutatingTableReference,
Supplier<Consumer<ColumnConsumer>> columnsToMatchVisitationSupplier,
Supplier<Consumer<SelectionConsumer>> columnsToMatchVisitationSupplier,
ExecutionContext executionContext) {
// Not "yet" implemented. Not sure we will. This requires the ability to define
// "in-line views" with a table-ctor which the SQL AST does not yet define support for

View File

@ -44,6 +44,7 @@ import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.CompositeSqmPathSource;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.QueryLogging;
import org.hibernate.query.SemanticException;
@ -123,6 +124,7 @@ import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmBooleanExpressionPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmEmptinessPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmExistsPredicate;
@ -176,6 +178,7 @@ import org.hibernate.sql.ast.tree.expression.Format;
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
import org.hibernate.sql.ast.tree.expression.Star;
@ -196,6 +199,7 @@ import org.hibernate.sql.ast.tree.predicate.LikePredicate;
import org.hibernate.sql.ast.tree.predicate.NegatedPredicate;
import org.hibernate.sql.ast.tree.predicate.NullnessPredicate;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.predicate.SelfRenderingPredicate;
import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SelectClause;
import org.hibernate.sql.ast.tree.select.SelectStatement;
@ -1212,17 +1216,13 @@ public abstract class BaseSqmToSqlAstConverter
MappingModelExpressable valueMapping,
Consumer<JdbcParameter> jdbcParameterConsumer) {
if ( valueMapping instanceof Association ) {
( (Association) valueMapping ).getForeignKeyDescriptor().visitJdbcTypes(
jdbcMapping -> jdbcParameterConsumer.accept( new JdbcParameterImpl( jdbcMapping ) ),
getCurrentClauseStack().getCurrent(),
getCreationContext().getDomainModel().getTypeConfiguration()
( (Association) valueMapping ).getForeignKeyDescriptor().forEachJdbcType(
(index, jdbcMapping) -> jdbcParameterConsumer.accept( new JdbcParameterImpl( jdbcMapping ) )
);
}
else {
valueMapping.visitJdbcTypes(
jdbcMapping -> jdbcParameterConsumer.accept( new JdbcParameterImpl( jdbcMapping ) ),
getCurrentClauseStack().getCurrent(),
getCreationContext().getDomainModel().getTypeConfiguration()
valueMapping.forEachJdbcType(
(index, jdbcMapping) -> jdbcParameterConsumer.accept( new JdbcParameterImpl( jdbcMapping ) )
);
}
}
@ -2467,7 +2467,7 @@ public abstract class BaseSqmToSqlAstConverter
subQuerySpec.applyPredicate( tableGroupJoin.getPredicate() );
final ForeignKeyDescriptor collectionKeyDescriptor = pluralAttributeMapping.getKeyDescriptor();
final int jdbcTypeCount = collectionKeyDescriptor.getJdbcTypeCount( sessionFactory.getTypeConfiguration() );
final int jdbcTypeCount = collectionKeyDescriptor.getJdbcTypeCount();
assert jdbcTypeCount > 0;
final JdbcLiteral<Integer> jdbcLiteral = new JdbcLiteral<>( 1, StandardBasicTypes.INTEGER );
@ -2696,6 +2696,21 @@ public abstract class BaseSqmToSqlAstConverter
);
}
@Override
public Object visitBooleanExpressionPredicate(SqmBooleanExpressionPredicate predicate) {
Object booleanExpression = predicate.getBooleanExpression().accept( this );
if ( booleanExpression instanceof SelfRenderingExpression ) {
return new SelfRenderingPredicate( (SelfRenderingExpression) booleanExpression );
}
else {
return new ComparisonPredicate(
(Expression) booleanExpression,
ComparisonOperator.EQUAL,
new QueryLiteral<>( true, basicType( Boolean.class ) )
);
}
}
@Override
public Object visitExistsPredicate(SqmExistsPredicate predicate) {
return new ExistsPredicate( (QuerySpec) predicate.getExpression().accept( this ) );

View File

@ -51,15 +51,11 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
mapping.getMappedColumnExpression()
mapping.getSelectionExpression()
),
sacs -> new ColumnReference(
tableReference.getIdentificationVariable(),
mapping.getMappedColumnExpression(),
mapping.isMappedColumnExpressionFormula(),
mapping.getCustomReadExpression(),
mapping.getCustomWriteExpression(),
mapping.getJdbcMapping(),
mapping,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
);

View File

@ -43,15 +43,6 @@ public interface DomainResultProducer<T> {
* personMapping.getValueMapping( "name" );
*/
/**
* Visit all of the SqlExpressableTypes associated with this this Readable.
*
* Used during cacheable SQL AST creation.
*/
default void visitJdbcTypes(Consumer<JdbcMapping> action, TypeConfiguration typeConfiguration) {
throw new NotYetImplementedFor6Exception( getClass() );
}
/**
* Produce the domain query
*/

View File

@ -86,30 +86,25 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
toOneAttributeMapping
);
modelPart.visitColumns(
(containingTableExpression, columnExpression, isFormula, customReadExpression, customWriteExpression, jdbcMapping) -> {
final TableReference tf;
modelPart.forEachSelection(
(columnIndex, selection) -> {
final TableReference tableReference = getTableReference(
sqmPath,
sqlAstCreationState,
tableGroup,
toOneAttributeMapping,
containingTableExpression
selection.getContainingTableExpression()
);
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
columnExpression
selection.getSelectionExpression()
),
sqlAstProcessingState -> new ColumnReference(
tableReference.getIdentificationVariable(),
columnExpression,
isFormula,
customReadExpression,
customWriteExpression,
jdbcMapping,
selection,
sqlAstCreationState.getCreationContext().getSessionFactory()
)
);

View File

@ -235,20 +235,16 @@ public class StandardSqmUpdateTranslator
final List<JdbcParameter> jdbcParametersForSqm = new ArrayList<>();
// create one JdbcParameter for each column in the assigned path
assignedPathInterpretation.getExpressionType().visitColumns(
(containingTableExpression, columnExpression, isFormula, customReadExpr, customWriteExpr, jdbcMapping) -> {
final JdbcParameter jdbcParameter = new JdbcParameterImpl( jdbcMapping );
assignedPathInterpretation.getExpressionType().forEachSelection(
(columnIndex, selection) -> {
final JdbcParameter jdbcParameter = new JdbcParameterImpl( selection.getJdbcMapping() );
jdbcParametersForSqm.add( jdbcParameter );
assignments.add(
new Assignment(
new ColumnReference(
// we do not want a qualifier (table alias) here
(String) null,
columnExpression,
isFormula,
customReadExpr,
customWriteExpr,
jdbcMapping,
selection,
getCreationContext().getSessionFactory()
),
jdbcParameter
@ -265,8 +261,8 @@ public class StandardSqmUpdateTranslator
final Expression valueExpression = (Expression) sqmAssignment.getValue().accept( this );
final int valueExprJdbcCount = valueExpression.getExpressionType().getJdbcTypeCount( typeConfiguration );
final int assignedPathJdbcCount = assignedPathInterpretation.getExpressionType().getJdbcTypeCount( typeConfiguration );
final int valueExprJdbcCount = valueExpression.getExpressionType().getJdbcTypeCount();
final int assignedPathJdbcCount = assignedPathInterpretation.getExpressionType().getJdbcTypeCount();
if ( valueExprJdbcCount != assignedPathJdbcCount ) {
SqlTreeCreationLogger.LOGGER.debugf(

View File

@ -7,16 +7,9 @@
package org.hibernate.query.sqm.tree.domain;
import java.util.Locale;
import java.util.function.Consumer;
import org.hibernate.HibernateException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.NodeBuilder;
@ -24,9 +17,7 @@ import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.sql.ast.Clause;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -87,33 +78,4 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> implemen
}
@Override
public void visitJdbcTypes(Consumer<JdbcMapping> action, TypeConfiguration typeConfiguration) {
// todo (6.0) : better as some form of PersistentAttribute -> org.hibernate.persister.walking.spi.AttributeDefinition resolution
final SingularPersistentAttribute<O, T> attribute = getReferencedPathSource();
final ManagedDomainType<O> attributeType = (ManagedDomainType<O>) attribute.getType();
if ( attributeType instanceof EntityDomainType<?> ) {
final EntityDomainType<?> entityDomainType = (EntityDomainType<?>) attributeType;
final String entityName = entityDomainType.getHibernateEntityName();
final EntityPersister entityDescriptor = typeConfiguration.getSessionFactory()
.getMetamodel()
.getEntityDescriptor( entityName );
entityDescriptor.visitSubParts(
valueMapping -> valueMapping.visitJdbcTypes(
action,
Clause.IRRELEVANT,
typeConfiguration
),
entityDescriptor
);
}
else if ( attributeType instanceof EmbeddableDomainType<?> ) {
throw new NotYetImplementedFor6Exception( getClass() );
}
else {
throw new HibernateException( "Unexpected declaring " );
}
}
}

View File

@ -6,9 +6,6 @@
*/
package org.hibernate.query.sqm.tree.from;
import java.util.function.Consumer;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.PathException;
@ -22,11 +19,9 @@ import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
import org.hibernate.sql.ast.Clause;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
@ -114,22 +109,6 @@ public class SqmRoot<E> extends AbstractSqmFrom<E,E> implements JpaRoot<E>, Doma
return new SqmTreatedRoot<>( this, treatTarget, nodeBuilder() );
}
@Override
public void visitJdbcTypes(Consumer<JdbcMapping> action, TypeConfiguration typeConfiguration) {
final String entityName = getReferencedPathSource().getHibernateEntityName();
final EntityPersister entityDescriptor = typeConfiguration.getSessionFactory()
.getMetamodel()
.getEntityDescriptor( entityName );
entityDescriptor.visitSubParts(
valueMapping -> valueMapping.visitJdbcTypes(
action,
Clause.IRRELEVANT,
typeConfiguration
),
entityDescriptor
);
}
@Override
public DomainResult<E> createDomainResult(

View File

@ -21,7 +21,7 @@ public class ANSICaseExpressionWalker implements CaseExpressionWalker {
CaseSearchedExpression caseSearchedExpression,
StringBuilder sqlBuffer,
SqlAstWalker sqlAstWalker){
sqlBuffer.append( "case " );
sqlBuffer.append( "case" );
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {
sqlBuffer.append( " when " );

View File

@ -919,7 +919,7 @@ public abstract class AbstractSqlAstWalker
else if ( modelPart instanceof PluralAttributeMapping ) {
CollectionPart elementDescriptor = ( (PluralAttributeMapping) modelPart ).getElementDescriptor();
if ( elementDescriptor instanceof BasicValuedCollectionPart ) {
String mappedColumnExpression = ( (BasicValuedCollectionPart) elementDescriptor ).getMappedColumnExpression();
String mappedColumnExpression = ( (BasicValuedCollectionPart) elementDescriptor ).getSelectionExpression();
appendSql( mappedColumnExpression );
}
}
@ -1384,7 +1384,7 @@ public abstract class AbstractSqlAstWalker
@Override
public void visitCaseSimpleExpression(CaseSimpleExpression caseSimpleExpression) {
appendSql( "case " );
appendSql( "case" );
caseSimpleExpression.getFixture().accept( this );
for ( CaseSimpleExpression.WhenFragment whenFragment : caseSimpleExpression.getWhenFragments() ) {
appendSql( " when " );
@ -1431,7 +1431,7 @@ public abstract class AbstractSqlAstWalker
appendSql( SqlAppender.NULL_KEYWORD );
}
else {
assert literal.getExpressionType().getJdbcTypeCount( getTypeConfiguration() ) == 1;
assert literal.getExpressionType().getJdbcTypeCount() == 1;
final JdbcMapping jdbcMapping = literal.getJdbcMapping();
final JdbcLiteralFormatter literalFormatter = jdbcMapping.getSqlTypeDescriptor().getJdbcLiteralFormatter( jdbcMapping.getJavaTypeDescriptor() );
if ( literalFormatter == null ) {
@ -1470,7 +1470,8 @@ public abstract class AbstractSqlAstWalker
@Override
public void visitSelfRenderingPredicate(SelfRenderingPredicate selfRenderingPredicate) {
selfRenderingPredicate.getSelfRenderingExpression().accept( this );
// todo (6.0) render boolean expression as comparison predicate if necessary
selfRenderingPredicate.getSelfRenderingExpression().renderToSql( this, this, getSessionFactory() );
}
@Override

View File

@ -24,7 +24,7 @@ public class DerbyCaseExpressionWalker implements CaseExpressionWalker {
StringBuilder sqlBuffer,
SqlAstWalker sqlAstWalker) {
sqlBuffer.append( "case " );
sqlBuffer.append( "case" );
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {
sqlBuffer.append( " when " );

View File

@ -20,7 +20,7 @@ public class MckoiCaseExpressionWalker implements CaseExpressionWalker {
@Override
public void visitCaseSearchedExpression(
CaseSearchedExpression caseSearchedExpression, StringBuilder sqlBuffer, SqlAstWalker sqlAstWalker) {
sqlBuffer.append( "case " );
sqlBuffer.append( "case" );
StringBuilder buf2= new StringBuilder( );
for ( CaseSearchedExpression.WhenFragment whenFragment : caseSearchedExpression.getWhenFragments() ) {

Some files were not shown because too many files have changed in this diff Show More