HHH-14318 Introduce column mapping abstract to support formulas easily
This commit is contained in:
parent
cb7c65e49d
commit
4de1870785
|
@ -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;
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -73,7 +73,7 @@ public class Property implements Serializable, MetaAttributable {
|
|||
return value.getColumnSpan();
|
||||
}
|
||||
|
||||
public Iterator getColumnIterator() {
|
||||
public Iterator<Selectable> getColumnIterator() {
|
||||
return value.getColumnIterator();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 -> {
|
||||
if ( attribute instanceof ToOneAttributeMapping ) {
|
||||
final ToOneAttributeMapping associationAttributeMapping = (ToOneAttributeMapping) attribute;
|
||||
associationAttributeMapping.getForeignKeyDescriptor().visitReferringColumns( consumer );
|
||||
}
|
||||
else {
|
||||
attribute.visitColumns( consumer );
|
||||
}
|
||||
}
|
||||
);
|
||||
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;
|
||||
span += associationAttributeMapping.getForeignKeyDescriptor().visitReferringColumns(
|
||||
span + offset,
|
||||
consumer
|
||||
);
|
||||
}
|
||||
else {
|
||||
span += attribute.forEachSelection( span + offset, consumer );
|
||||
}
|
||||
}
|
||||
return span;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,35 +190,36 @@ 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 -> {
|
||||
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
|
||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||
final EntityMappingType associatedEntityMappingType =
|
||||
( (ToOneAttributeMapping) attributeMapping ).getAssociatedEntityMappingType();
|
||||
final EntityIdentifierMapping identifierMapping =
|
||||
associatedEntityMappingType.getIdentifierMapping();
|
||||
final Object identifier = identifierMapping.getIdentifier( o, session );
|
||||
identifierMapping.visitJdbcValues( identifier, clause, valuesConsumer, session );
|
||||
}
|
||||
else {
|
||||
attributeMapping.visitJdbcValues( o, clause, valuesConsumer, session );
|
||||
}
|
||||
}
|
||||
);
|
||||
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 =
|
||||
( (ToOneAttributeMapping) attributeMapping ).getAssociatedEntityMappingType();
|
||||
final EntityIdentifierMapping identifierMapping =
|
||||
associatedEntityMappingType.getIdentifierMapping();
|
||||
final Object identifier = identifierMapping.getIdentifier( o, session );
|
||||
span += identifierMapping.forEachJdbcValue(
|
||||
identifier,
|
||||
clause,
|
||||
span + offset,
|
||||
valuesConsumer,
|
||||
session
|
||||
);
|
||||
}
|
||||
else {
|
||||
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;
|
||||
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,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
selection,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
@Override
|
||||
public void accept(JdbcMapping jdbcMapping) {
|
||||
final String attrColumnExpr = attrColumnNames.get( index++ );
|
||||
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver()
|
||||
.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
attrColumnExpr
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
attrColumnExpr,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
},
|
||||
clause,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
);
|
||||
|
||||
return new SqlTuple( columnReferences, this );
|
||||
|
@ -326,4 +298,5 @@ public abstract class AbstractCompositeIdentifierMapping
|
|||
protected EntityMappingType getEntityMapping() {
|
||||
return entityMapping;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,28 +173,48 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
|||
if ( subtype instanceof BasicType ) {
|
||||
final BasicValue basicValue = (BasicValue) bootPropertyDescriptor.getValue();
|
||||
final Selectable selectable = basicValue.getColumn();
|
||||
|
||||
final String mappedColumnExpression = mappedColumnExpressions.get( columnPosition++ );
|
||||
|
||||
attributeMappings.put(
|
||||
bootPropertyDescriptor.getName(),
|
||||
MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
(BasicType<?>) subtype,
|
||||
containingTableExpression,
|
||||
mappedColumnExpression,
|
||||
false,
|
||||
selectable.getCustomReadExpression(),
|
||||
selectable.getCustomWriteExpression(),
|
||||
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
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];
|
||||
}
|
||||
|
||||
BasicValuedSingularAttributeMapping attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
(BasicType<?>) subtype,
|
||||
containingTableExpression,
|
||||
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,79 +302,70 @@ public class EmbeddableMappingType implements ManagedMappingType {
|
|||
}
|
||||
};
|
||||
|
||||
attributeMappings.put(
|
||||
bootPropertyDescriptor.getName(),
|
||||
new DiscriminatedAssociationAttributeMapping(
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Object.class ),
|
||||
this,
|
||||
attributeIndex,
|
||||
attributeMetadataAccess,
|
||||
bootPropertyDescriptor.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE,
|
||||
propertyAccess,
|
||||
bootPropertyDescriptor,
|
||||
anyType,
|
||||
bootValueMapping,
|
||||
creationProcess
|
||||
)
|
||||
DiscriminatedAssociationAttributeMapping attributeMapping = new DiscriminatedAssociationAttributeMapping(
|
||||
valueMapping.getNavigableRole().append( bootPropertyDescriptor.getName() ),
|
||||
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Object.class ),
|
||||
this,
|
||||
attributeIndex,
|
||||
attributeMetadataAccess,
|
||||
bootPropertyDescriptor.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE,
|
||||
propertyAccess,
|
||||
bootPropertyDescriptor,
|
||||
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(
|
||||
EmbeddedAttributeMapping attributeMapping = MappingModelCreationHelper.buildEmbeddedAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
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 ),
|
||||
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex ),
|
||||
creationProcess
|
||||
)
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
this,
|
||||
subCompositeType,
|
||||
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(
|
||||
PluralAttributeMapping attributeMapping = MappingModelCreationHelper.buildPluralAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
MappingModelCreationHelper.buildPluralAttributeMapping(
|
||||
bootPropertyDescriptor.getName(),
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
compositeType.getCascadeStyle( attributeIndex),
|
||||
compositeType.getFetchMode( attributeIndex ),
|
||||
creationProcess
|
||||
)
|
||||
attributeIndex,
|
||||
bootPropertyDescriptor,
|
||||
entityPersister,
|
||||
representationStrategy.resolvePropertyAccess( bootPropertyDescriptor ),
|
||||
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;
|
||||
}
|
||||
if ( attributeMapping instanceof ToOneAttributeMapping ) {
|
||||
( (ToOneAttributeMapping) attributeMapping ).getKeyTargetMatchPart().visitJdbcTypes(
|
||||
action,
|
||||
clause,
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
else {
|
||||
attributeMapping.visitJdbcTypes( action, clause, typeConfiguration );
|
||||
}
|
||||
public int getJdbcTypeCount() {
|
||||
return selectionMappings.getJdbcTypeCount();
|
||||
}
|
||||
|
||||
@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,21 +605,14 @@ 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()
|
||||
.resolveAttributeMetadata( null )
|
||||
.getPropertyAccess()
|
||||
.getSetter()
|
||||
.set( compositeInstance, resolvedValues[i++], sessionFactory );
|
||||
}
|
||||
}
|
||||
);
|
||||
for ( int i = 0; i < attributes.size(); i++ ) {
|
||||
attributes.get( i )
|
||||
.getAttributeMetadataAccess()
|
||||
.resolveAttributeMetadata( null )
|
||||
.getPropertyAccess()
|
||||
.getSetter()
|
||||
.set( compositeInstance, resolvedValues[i], sessionFactory );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCreateEmptyCompositesEnabled() {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
attribute -> {
|
||||
final DomainResultAssembler assembler = assemblerMapping.get( attribute );
|
||||
final Object value = assembler == null ? UNFETCHED_PROPERTY : assembler.assemble( rowProcessingState );
|
||||
|
||||
@Override
|
||||
public void accept(StateArrayContributorMapping 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
selection,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
@Override
|
||||
public void accept(JdbcMapping jdbcMapping) {
|
||||
position++;
|
||||
|
||||
final String attrColumnExpr = attrColumnNames[ position ];
|
||||
final String attrColumnCustomReadExpr = customReadExpressions[ position ];
|
||||
final String attrColumnCustomWriteExpr = customWriteExpressions[ position ];
|
||||
|
||||
final Expression columnReference = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
attrColumnExpr
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
attrColumnExpr,
|
||||
false,
|
||||
attrColumnCustomReadExpr,
|
||||
attrColumnCustomWriteExpr,
|
||||
jdbcMapping,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
},
|
||||
clause,
|
||||
sqlAstCreationState.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
columnReferences.add( (ColumnReference) columnReference );
|
||||
}
|
||||
);
|
||||
|
||||
return new SqlTuple( columnReferences, this );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
columnExpression
|
||||
List<SqlSelection> sqlSelections = new ArrayList<>( targetSelectionMappings.getJdbcTypeCount() );
|
||||
targetSelectionMappings.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
selection,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
columnExpression,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
selection.getJdbcMapping().getJavaTypeDescriptor(),
|
||||
sqlAstCreationState.getCreationContext()
|
||||
.getDomainModel()
|
||||
.getTypeConfiguration()
|
||||
);
|
||||
sqlSelections.add( sqlSelection );
|
||||
}
|
||||
);
|
||||
|
||||
),
|
||||
jdbcMapping.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 );
|
||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
columnExpression
|
||||
List<SqlSelection> sqlSelections = new ArrayList<>( keySelectionMappings.getJdbcTypeCount() );
|
||||
keySelectionMappings.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
selection,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
columnExpression,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
),
|
||||
jdbcMapping.getJavaTypeDescriptor(),
|
||||
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
sqlSelections.add( sqlSelection );
|
||||
}
|
||||
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 );
|
||||
final ComparisonPredicate comparisonPredicate = new ComparisonPredicate(
|
||||
new ColumnReference(
|
||||
lhs,
|
||||
lhsExpressions.get( i ),
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationContext.getSessionFactory()
|
||||
),
|
||||
ComparisonOperator.EQUAL,
|
||||
new ColumnReference(
|
||||
rhs,
|
||||
rhsColumnExpressions.get( i ),
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationContext.getSessionFactory()
|
||||
)
|
||||
);
|
||||
predicate.add( comparisonPredicate );
|
||||
}
|
||||
lhsMappings.forEachSelection(
|
||||
(i, selection) -> {
|
||||
final ComparisonPredicate comparisonPredicate = new ComparisonPredicate(
|
||||
new ColumnReference(
|
||||
lhs,
|
||||
selection,
|
||||
creationContext.getSessionFactory()
|
||||
),
|
||||
ComparisonOperator.EQUAL,
|
||||
new ColumnReference(
|
||||
rhs,
|
||||
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 SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
|
||||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
columnExpression
|
||||
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,
|
||||
selection.getSelectionExpression()
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
selection,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
),
|
||||
s ->
|
||||
new ColumnReference(
|
||||
identificationVariable,
|
||||
columnExpression,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getSessionFactory()
|
||||
)
|
||||
),
|
||||
jdbcMapping.getJavaTypeDescriptor(),
|
||||
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||
);
|
||||
sqlSelections.add( sqlSelection );
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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();
|
||||
Object o = mapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = mapping.disassemble( o, session );
|
||||
i++;
|
||||
}
|
||||
final Object[] result = new Object[getAttributeCount()];
|
||||
forEachAttribute(
|
||||
(i, mapping) -> {
|
||||
Object o = mapping.getPropertyAccess().getGetter().get( value );
|
||||
result[i] = mapping.disassemble( o, session );
|
||||
}
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
setRefererencedAttributeForeignKeyDescriptor(
|
||||
attributeMapping,
|
||||
referencedAttributeMapping,
|
||||
referencedEntityDescriptor,
|
||||
referencedPropertyName,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
final ModelPart modelPart = referencedEntityDescriptor.findSubPart( referencedPropertyName );
|
||||
if ( modelPart instanceof ToOneAttributeMapping ) {
|
||||
setRefererencedAttributeForeignKeyDescriptor(
|
||||
attributeMapping,
|
||||
(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
|
||||
|
|
|
@ -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 ) ) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
.getBasicTypeForJavaType( attribute.getJavaType() );
|
||||
action.accept( basicType.getJdbcMapping() );
|
||||
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( 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
|
||||
|
|
|
@ -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,55 +1386,42 @@ 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;
|
||||
identifierMapping.forEachSelection(
|
||||
(columnIndex, selection) -> {
|
||||
final String rootPkColumnName = rootPkColumnNames[ columnIndex ];
|
||||
final Expression pkColumnExpression = sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
rootTableReference,
|
||||
rootPkColumnName
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTableReference.getIdentificationVariable(),
|
||||
selection,
|
||||
getFactory()
|
||||
)
|
||||
);
|
||||
|
||||
@Override
|
||||
public void accept(JdbcMapping jdbcMapping) {
|
||||
final String rootPkColumnName = rootPkColumnNames[ columnIndex ];
|
||||
final Expression pkColumnExpression = sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
rootTableReference,
|
||||
rootPkColumnName
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTableReference.getIdentificationVariable(),
|
||||
rootPkColumnName,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
getFactory()
|
||||
)
|
||||
);
|
||||
final String fkColumnName = fkColumnNames[ columnIndex ];
|
||||
final Expression fkColumnExpression = sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
joinedTableReference,
|
||||
fkColumnName
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
joinedTableReference.getIdentificationVariable(),
|
||||
fkColumnName,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
selection.getJdbcMapping(),
|
||||
getFactory()
|
||||
)
|
||||
);
|
||||
|
||||
final String fkColumnName = fkColumnNames[ columnIndex ];
|
||||
final Expression fkColumnExpression = sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
joinedTableReference,
|
||||
fkColumnName
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
joinedTableReference.getIdentificationVariable(),
|
||||
fkColumnName,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
jdbcMapping,
|
||||
getFactory()
|
||||
)
|
||||
);
|
||||
|
||||
conjunction.add( new ComparisonPredicate( pkColumnExpression, ComparisonOperator.EQUAL, fkColumnExpression ) );
|
||||
|
||||
columnIndex++;
|
||||
}
|
||||
},
|
||||
Clause.IRRELEVANT,
|
||||
getFactory().getTypeConfiguration()
|
||||
conjunction.add( new ComparisonPredicate( pkColumnExpression, ComparisonOperator.EQUAL, fkColumnExpression ) );
|
||||
}
|
||||
);
|
||||
|
||||
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
|
||||
|
|
|
@ -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() ),
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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++ );
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( jdbcType, null )
|
||||
);
|
||||
}
|
||||
},
|
||||
Clause.IRRELEVANT,
|
||||
session.getFactory().getTypeConfiguration()
|
||||
mappingExpressable.forEachJdbcType(
|
||||
(position, jdbcType) -> {
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParams.get( position ),
|
||||
new JdbcParameterBindingImpl( jdbcType, null )
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
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(
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 " );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 " );
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue