@@ -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