Skip to content

Commit b20e686

Browse files
committed
HHH-19712 Rework select fragment generation to work with column selection deduplication
1 parent e357528 commit b20e686

File tree

1 file changed

+87
-75
lines changed

1 file changed

+87
-75
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 87 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,61 +1999,62 @@ public String selectFragment(String alias, String suffix) {
19991999
// Wrap expressions with aliases
20002000
final SelectClause selectClause = rootQuerySpec.getSelectClause();
20012001
final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
2002+
final Set<String> processedExpressions = new HashSet<>( sqlSelections.size() );
20022003
int i = 0;
2003-
int columnIndex = 0;
2004-
final String[] columnAliases = getSubclassColumnAliasClosure();
2005-
final int columnAliasesSize = columnAliases.length;
2006-
for ( String identifierAlias : identifierAliases ) {
2007-
sqlSelections.set(
2008-
i,
2009-
new SqlSelectionImpl(
2010-
i,
2011-
new AliasedExpression( sqlSelections.get( i ).getExpression(), identifierAlias + suffix )
2012-
)
2013-
);
2014-
if ( i < columnAliasesSize && columnAliases[i].equals( identifierAlias ) ) {
2015-
columnIndex++;
2004+
final int identifierSelectionSize = identifierMapping.getJdbcTypeCount();
2005+
for ( int j = 0; j < identifierSelectionSize; j++ ) {
2006+
final SelectableMapping selectableMapping = identifierMapping.getSelectable( j );
2007+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2008+
aliasSelection( sqlSelections, i, identifierAliases[j] + suffix );
2009+
i++;
20162010
}
2017-
i++;
20182011
}
20192012

2020-
if ( entityMetamodel.hasSubclasses() ) {
2021-
sqlSelections.set(
2022-
i,
2023-
new SqlSelectionImpl(
2024-
i,
2025-
new AliasedExpression( sqlSelections.get( i ).getExpression(), getDiscriminatorAlias() + suffix )
2026-
)
2027-
);
2028-
i++;
2013+
if ( hasSubclasses() ) {
2014+
assert discriminatorMapping.getJdbcTypeCount() == 1;
2015+
final SelectableMapping selectableMapping = discriminatorMapping.getSelectable( 0 );
2016+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2017+
aliasSelection( sqlSelections, i, getDiscriminatorAlias() + suffix );
2018+
i++;
2019+
}
20292020
}
20302021

20312022
if ( hasRowId() ) {
2032-
sqlSelections.set(
2033-
i,
2034-
new SqlSelectionImpl(
2035-
i,
2036-
new AliasedExpression( sqlSelections.get( i ).getExpression(), ROWID_ALIAS + suffix )
2037-
)
2038-
);
2039-
i++;
2023+
final SelectableMapping selectableMapping = rowIdMapping;
2024+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2025+
aliasSelection( sqlSelections, i, ROWID_ALIAS + suffix );
2026+
i++;
2027+
}
20402028
}
20412029

2030+
final String[] columnAliases = getSubclassColumnAliasClosure();
20422031
final String[] formulaAliases = getSubclassFormulaAliasClosure();
2032+
int columnIndex = 0;
20432033
int formulaIndex = 0;
2044-
for ( ; i < sqlSelections.size(); i++ ) {
2045-
final SqlSelection sqlSelection = sqlSelections.get( i );
2046-
final ColumnReference columnReference = (ColumnReference) sqlSelection.getExpression();
2047-
final String selectAlias = !columnReference.isColumnExpressionFormula()
2048-
? columnAliases[columnIndex++] + suffix
2049-
: formulaAliases[formulaIndex++] + suffix;
2050-
sqlSelections.set(
2051-
i,
2052-
new SqlSelectionImpl(
2053-
sqlSelection.getValuesArrayPosition(),
2054-
new AliasedExpression( sqlSelection.getExpression(), selectAlias )
2055-
)
2056-
);
2034+
final int size = getNumberOfFetchables();
2035+
// getSubclassColumnAliasClosure contains the _identifierMapper columns when it has an id class,
2036+
// which need to be skipped
2037+
if ( identifierMapping instanceof NonAggregatedIdentifierMapping
2038+
&& ( (NonAggregatedIdentifierMapping) identifierMapping ).getIdClassEmbeddable() != null ) {
2039+
columnIndex = identifierSelectionSize;
2040+
}
2041+
for ( int j = 0; j < size; j++ ) {
2042+
final AttributeMapping fetchable = getFetchable( j );
2043+
if ( !(fetchable instanceof PluralAttributeMapping)
2044+
&& !skipFetchable( fetchable, fetchable.getMappedFetchOptions().getTiming() )
2045+
&& fetchable.isSelectable() ) {
2046+
final int jdbcTypeCount = fetchable.getJdbcTypeCount();
2047+
for ( int k = 0; k < jdbcTypeCount; k++ ) {
2048+
final SelectableMapping selectableMapping = fetchable.getSelectable( k );
2049+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2050+
final String baseAlias = selectableMapping.isFormula()
2051+
? formulaAliases[formulaIndex++]
2052+
: columnAliases[columnIndex++];
2053+
aliasSelection( sqlSelections, i, baseAlias + suffix );
2054+
i++;
2055+
}
2056+
}
2057+
}
20572058
}
20582059

20592060
final String sql = getFactory().getJdbcServices()
@@ -2073,6 +2074,17 @@ public String selectFragment(String alias, String suffix) {
20732074
return expression;
20742075
}
20752076

2077+
private static void aliasSelection(
2078+
List<SqlSelection> sqlSelections,
2079+
int selectionIndex,
2080+
String alias) {
2081+
final Expression expression = sqlSelections.get( selectionIndex ).getExpression();
2082+
sqlSelections.set(
2083+
selectionIndex,
2084+
new SqlSelectionImpl( selectionIndex, new AliasedExpression( expression, alias ) )
2085+
);
2086+
}
2087+
20762088
private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstCreationState creationState) {
20772089
final FetchableContainer fetchableContainer = fetchParent.getReferencedMappingContainer();
20782090
final int size = fetchableContainer.getNumberOfFetchables();
@@ -2083,45 +2095,45 @@ private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstC
20832095
// Ignore plural attributes
20842096
if ( !( fetchable instanceof PluralAttributeMapping ) ) {
20852097
final FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
2086-
if ( fetchable.asBasicValuedModelPart() != null ) {
2087-
// Ignore lazy basic columns
2088-
if ( fetchTiming == FetchTiming.DELAYED ) {
2089-
continue;
2098+
if ( !skipFetchable( fetchable, fetchTiming ) ) {
2099+
if ( fetchTiming == null ) {
2100+
throw new AssertionFailure( "fetchTiming was null" );
20902101
}
2091-
}
2092-
else if ( fetchable instanceof Association ) {
2093-
final Association association = (Association) fetchable;
2094-
// Ignore the fetchable if the FK is on the other side
2095-
if ( association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET ) {
2096-
continue;
2097-
}
2098-
// Ensure the FK comes from the root table
2099-
if ( !getRootTableName().equals( association.getForeignKeyDescriptor().getKeyTable() ) ) {
2100-
continue;
2102+
if ( fetchable.isSelectable() ) {
2103+
final Fetch fetch = fetchParent.generateFetchableFetch(
2104+
fetchable,
2105+
fetchParent.resolveNavigablePath( fetchable ),
2106+
fetchTiming,
2107+
false,
2108+
null,
2109+
creationState
2110+
);
2111+
fetches.add( fetch );
21012112
}
21022113
}
2103-
2104-
if ( fetchTiming == null ) {
2105-
throw new AssertionFailure("fetchTiming was null");
2106-
}
2107-
2108-
if ( fetchable.isSelectable() ) {
2109-
final Fetch fetch = fetchParent.generateFetchableFetch(
2110-
fetchable,
2111-
fetchParent.resolveNavigablePath( fetchable ),
2112-
fetchTiming,
2113-
false,
2114-
null,
2115-
creationState
2116-
);
2117-
fetches.add( fetch );
2118-
}
21192114
}
21202115
}
21212116

21222117
return fetches.build();
21232118
}
21242119

2120+
private boolean skipFetchable(Fetchable fetchable, FetchTiming fetchTiming) {
2121+
if ( fetchable.asBasicValuedModelPart() != null ) {
2122+
// Ignore lazy basic columns
2123+
return fetchTiming == FetchTiming.DELAYED;
2124+
}
2125+
else if ( fetchable instanceof Association ) {
2126+
final Association association = (Association) fetchable;
2127+
// Ignore the fetchable if the FK is on the other side
2128+
return association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET
2129+
// Ensure the FK comes from the root table
2130+
|| !getRootTableName().equals( association.getForeignKeyDescriptor().getKeyTable() );
2131+
}
2132+
else {
2133+
return false;
2134+
}
2135+
}
2136+
21252137
/**
21262138
* @deprecated use {@link Fetchable#isSelectable()} instead.
21272139
*/
@@ -6354,7 +6366,7 @@ public Fetchable getKeyFetchable(int position) {
63546366
}
63556367

63566368
@Override
6357-
public Fetchable getFetchable(int position) {
6369+
public AttributeMapping getFetchable(int position) {
63586370
return getStaticFetchableList().get( position );
63596371
}
63606372

0 commit comments

Comments
 (0)