@@ -1999,61 +1999,56 @@ 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+ for ( int j = 0 ; j < size ; j ++ ) {
2036+ final AttributeMapping fetchable = getFetchable ( j );
2037+ if ( !(fetchable instanceof PluralAttributeMapping )
2038+ && !skipFetchable ( fetchable , fetchable .getMappedFetchOptions ().getTiming () )
2039+ && fetchable .isSelectable () ) {
2040+ final int jdbcTypeCount = fetchable .getJdbcTypeCount ();
2041+ for ( int k = 0 ; k < jdbcTypeCount ; k ++ ) {
2042+ final SelectableMapping selectableMapping = fetchable .getSelectable ( k );
2043+ final String baseAlias = selectableMapping .isFormula ()
2044+ ? formulaAliases [formulaIndex ++]
2045+ : columnAliases [columnIndex ++];
2046+ if ( processedExpressions .add ( selectableMapping .getSelectionExpression () ) ) {
2047+ aliasSelection ( sqlSelections , i , baseAlias + suffix );
2048+ i ++;
2049+ }
2050+ }
2051+ }
20572052 }
20582053
20592054 final String sql = getFactory ().getJdbcServices ()
@@ -2073,6 +2068,17 @@ public String selectFragment(String alias, String suffix) {
20732068 return expression ;
20742069 }
20752070
2071+ private static void aliasSelection (
2072+ List <SqlSelection > sqlSelections ,
2073+ int selectionIndex ,
2074+ String alias ) {
2075+ final Expression expression = sqlSelections .get ( selectionIndex ).getExpression ();
2076+ sqlSelections .set (
2077+ selectionIndex ,
2078+ new SqlSelectionImpl ( selectionIndex , new AliasedExpression ( expression , alias ) )
2079+ );
2080+ }
2081+
20762082 private ImmutableFetchList fetchProcessor (FetchParent fetchParent , LoaderSqlAstCreationState creationState ) {
20772083 final FetchableContainer fetchableContainer = fetchParent .getReferencedMappingContainer ();
20782084 final int size = fetchableContainer .getNumberOfFetchables ();
@@ -2083,45 +2089,45 @@ private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstC
20832089 // Ignore plural attributes
20842090 if ( !( fetchable instanceof PluralAttributeMapping ) ) {
20852091 final FetchTiming fetchTiming = fetchable .getMappedFetchOptions ().getTiming ();
2086- if ( fetchable .asBasicValuedModelPart () != null ) {
2087- // Ignore lazy basic columns
2088- if ( fetchTiming == FetchTiming .DELAYED ) {
2089- continue ;
2090- }
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 ;
2101- }
2102- }
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- }
2092+ if ( !skipFetchable ( fetchable , fetchTiming ) ) {
2093+ if ( fetchTiming == null ) {
2094+ throw new AssertionFailure ( "fetchTiming was null" );
2095+ }
2096+ if ( fetchable .isSelectable () ) {
2097+ final Fetch fetch = fetchParent .generateFetchableFetch (
2098+ fetchable ,
2099+ fetchParent .resolveNavigablePath ( fetchable ),
2100+ fetchTiming ,
2101+ false ,
2102+ null ,
2103+ creationState
2104+ );
2105+ fetches .add ( fetch );
2106+ }
2107+ }
21192108 }
21202109 }
21212110
21222111 return fetches .build ();
21232112 }
21242113
2114+ private boolean skipFetchable (Fetchable fetchable , FetchTiming fetchTiming ) {
2115+ if ( fetchable .asBasicValuedModelPart () != null ) {
2116+ // Ignore lazy basic columns
2117+ return fetchTiming == FetchTiming .DELAYED ;
2118+ }
2119+ else if ( fetchable instanceof Association ) {
2120+ final Association association = (Association ) fetchable ;
2121+ // Ignore the fetchable if the FK is on the other side
2122+ return association .getSideNature () == ForeignKeyDescriptor .Nature .TARGET
2123+ // Ensure the FK comes from the root table
2124+ || !getRootTableName ().equals ( association .getForeignKeyDescriptor ().getKeyTable () );
2125+ }
2126+ else {
2127+ return false ;
2128+ }
2129+ }
2130+
21252131 /**
21262132 * @deprecated use {@link Fetchable#isSelectable()} instead.
21272133 */
@@ -6354,7 +6360,7 @@ public Fetchable getKeyFetchable(int position) {
63546360 }
63556361
63566362 @ Override
6357- public Fetchable getFetchable (int position ) {
6363+ public AttributeMapping getFetchable (int position ) {
63586364 return getStaticFetchableList ().get ( position );
63596365 }
63606366
0 commit comments