@@ -1791,61 +1791,62 @@ public String selectFragment(String alias, String suffix) {
1791
1791
// Wrap expressions with aliases
1792
1792
final SelectClause selectClause = rootQuerySpec .getSelectClause ();
1793
1793
final List <SqlSelection > sqlSelections = selectClause .getSqlSelections ();
1794
+ final Set <String > processedExpressions = new HashSet <>( sqlSelections .size () );
1794
1795
int i = 0 ;
1795
- int columnIndex = 0 ;
1796
- final String [] columnAliases = getSubclassColumnAliasClosure ();
1797
- final int columnAliasesSize = columnAliases .length ;
1798
- for ( String identifierAlias : identifierAliases ) {
1799
- sqlSelections .set (
1800
- i ,
1801
- new SqlSelectionImpl (
1802
- i ,
1803
- new AliasedExpression ( sqlSelections .get ( i ).getExpression (), identifierAlias + suffix )
1804
- )
1805
- );
1806
- if ( i < columnAliasesSize && columnAliases [i ].equals ( identifierAlias ) ) {
1807
- columnIndex ++;
1796
+ final int identifierSelectionSize = identifierMapping .getJdbcTypeCount ();
1797
+ for ( int j = 0 ; j < identifierSelectionSize ; j ++ ) {
1798
+ final SelectableMapping selectableMapping = identifierMapping .getSelectable ( j );
1799
+ if ( processedExpressions .add ( selectableMapping .getSelectionExpression () ) ) {
1800
+ aliasSelection ( sqlSelections , i , identifierAliases [j ] + suffix );
1801
+ i ++;
1808
1802
}
1809
- i ++;
1810
1803
}
1811
1804
1812
- if ( entityMetamodel .hasSubclasses () ) {
1813
- sqlSelections .set (
1814
- i ,
1815
- new SqlSelectionImpl (
1816
- i ,
1817
- new AliasedExpression ( sqlSelections .get ( i ).getExpression (), getDiscriminatorAlias () + suffix )
1818
- )
1819
- );
1820
- i ++;
1805
+ if ( hasSubclasses () ) {
1806
+ assert discriminatorMapping .getJdbcTypeCount () == 1 ;
1807
+ final SelectableMapping selectableMapping = discriminatorMapping .getSelectable ( 0 );
1808
+ if ( processedExpressions .add ( selectableMapping .getSelectionExpression () ) ) {
1809
+ aliasSelection ( sqlSelections , i , getDiscriminatorAlias () + suffix );
1810
+ i ++;
1811
+ }
1821
1812
}
1822
1813
1823
1814
if ( hasRowId () ) {
1824
- sqlSelections .set (
1825
- i ,
1826
- new SqlSelectionImpl (
1827
- i ,
1828
- new AliasedExpression ( sqlSelections .get ( i ).getExpression (), ROWID_ALIAS + suffix )
1829
- )
1830
- );
1831
- i ++;
1815
+ final SelectableMapping selectableMapping = rowIdMapping ;
1816
+ if ( processedExpressions .add ( selectableMapping .getSelectionExpression () ) ) {
1817
+ aliasSelection ( sqlSelections , i , ROWID_ALIAS + suffix );
1818
+ i ++;
1819
+ }
1832
1820
}
1833
1821
1822
+ final String [] columnAliases = getSubclassColumnAliasClosure ();
1834
1823
final String [] formulaAliases = getSubclassFormulaAliasClosure ();
1824
+ int columnIndex = 0 ;
1835
1825
int formulaIndex = 0 ;
1836
- for ( ; i < sqlSelections .size (); i ++ ) {
1837
- final SqlSelection sqlSelection = sqlSelections .get ( i );
1838
- final ColumnReference columnReference = (ColumnReference ) sqlSelection .getExpression ();
1839
- final String selectAlias = !columnReference .isColumnExpressionFormula ()
1840
- ? columnAliases [columnIndex ++] + suffix
1841
- : formulaAliases [formulaIndex ++] + suffix ;
1842
- sqlSelections .set (
1843
- i ,
1844
- new SqlSelectionImpl (
1845
- sqlSelection .getValuesArrayPosition (),
1846
- new AliasedExpression ( sqlSelection .getExpression (), selectAlias )
1847
- )
1848
- );
1826
+ final int size = getNumberOfFetchables ();
1827
+ // getSubclassColumnAliasClosure contains the _identifierMapper columns when it has an id class,
1828
+ // which need to be skipped
1829
+ if ( identifierMapping instanceof NonAggregatedIdentifierMapping
1830
+ && ( (NonAggregatedIdentifierMapping ) identifierMapping ).getIdClassEmbeddable () != null ) {
1831
+ columnIndex = identifierSelectionSize ;
1832
+ }
1833
+ for ( int j = 0 ; j < size ; j ++ ) {
1834
+ final AttributeMapping fetchable = getFetchable ( j );
1835
+ if ( !(fetchable instanceof PluralAttributeMapping )
1836
+ && !skipFetchable ( fetchable , fetchable .getMappedFetchOptions ().getTiming () )
1837
+ && fetchable .isSelectable () ) {
1838
+ final int jdbcTypeCount = fetchable .getJdbcTypeCount ();
1839
+ for ( int k = 0 ; k < jdbcTypeCount ; k ++ ) {
1840
+ final SelectableMapping selectableMapping = fetchable .getSelectable ( k );
1841
+ if ( processedExpressions .add ( selectableMapping .getSelectionExpression () ) ) {
1842
+ final String baseAlias = selectableMapping .isFormula ()
1843
+ ? formulaAliases [formulaIndex ++]
1844
+ : columnAliases [columnIndex ++];
1845
+ aliasSelection ( sqlSelections , i , baseAlias + suffix );
1846
+ i ++;
1847
+ }
1848
+ }
1849
+ }
1849
1850
}
1850
1851
1851
1852
final String sql = getFactory ().getJdbcServices ()
@@ -1865,6 +1866,17 @@ public String selectFragment(String alias, String suffix) {
1865
1866
return expression ;
1866
1867
}
1867
1868
1869
+ private static void aliasSelection (
1870
+ List <SqlSelection > sqlSelections ,
1871
+ int selectionIndex ,
1872
+ String alias ) {
1873
+ final Expression expression = sqlSelections .get ( selectionIndex ).getExpression ();
1874
+ sqlSelections .set (
1875
+ selectionIndex ,
1876
+ new SqlSelectionImpl ( selectionIndex , new AliasedExpression ( expression , alias ) )
1877
+ );
1878
+ }
1879
+
1868
1880
private ImmutableFetchList fetchProcessor (FetchParent fetchParent , LoaderSqlAstCreationState creationState ) {
1869
1881
final FetchableContainer fetchableContainer = fetchParent .getReferencedMappingContainer ();
1870
1882
final int size = fetchableContainer .getNumberOfFetchables ();
@@ -1874,51 +1886,46 @@ private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstC
1874
1886
final Fetchable fetchable = fetchableContainer .getFetchable ( i );
1875
1887
// Ignore plural attributes
1876
1888
if ( !( fetchable instanceof PluralAttributeMapping ) ) {
1877
- final FetchTiming fetchTiming ;
1878
- if ( fetchable instanceof BasicValuedModelPart ) {
1879
- // Ignore lazy basic columns
1880
- fetchTiming = fetchable .getMappedFetchOptions ().getTiming ();
1881
- if ( fetchTiming == FetchTiming .DELAYED ) {
1882
- continue ;
1883
- }
1884
- }
1885
- else if ( fetchable instanceof Association ) {
1886
- final Association association = (Association ) fetchable ;
1887
- // Ignore the fetchable if the FK is on the other side
1888
- if ( association .getSideNature () == ForeignKeyDescriptor .Nature .TARGET ) {
1889
- continue ;
1889
+ final FetchTiming fetchTiming = fetchable .getMappedFetchOptions ().getTiming ();
1890
+ if ( !skipFetchable ( fetchable , fetchTiming ) ) {
1891
+ if ( fetchTiming == null ) {
1892
+ throw new AssertionFailure ( "fetchTiming was null" );
1890
1893
}
1891
- // Ensure the FK comes from the root table
1892
- if ( !getRootTableName ().equals ( association .getForeignKeyDescriptor ().getKeyTable () ) ) {
1893
- continue ;
1894
+ if ( fetchable .isSelectable () ) {
1895
+ final Fetch fetch = fetchParent .generateFetchableFetch (
1896
+ fetchable ,
1897
+ fetchParent .resolveNavigablePath ( fetchable ),
1898
+ fetchTiming ,
1899
+ false ,
1900
+ null ,
1901
+ creationState
1902
+ );
1903
+ fetches .add ( fetch );
1894
1904
}
1895
- fetchTiming = FetchTiming .DELAYED ;
1896
- }
1897
- else {
1898
- fetchTiming = fetchable .getMappedFetchOptions ().getTiming ();
1899
- }
1900
-
1901
- if ( fetchTiming == null ) {
1902
- throw new AssertionFailure ("fetchTiming was null" );
1903
- }
1904
-
1905
- if ( fetchable .isSelectable () ) {
1906
- final Fetch fetch = fetchParent .generateFetchableFetch (
1907
- fetchable ,
1908
- fetchParent .resolveNavigablePath ( fetchable ),
1909
- fetchTiming ,
1910
- true ,
1911
- null ,
1912
- creationState
1913
- );
1914
- fetches .add ( fetch );
1915
1905
}
1916
1906
}
1917
1907
}
1918
1908
1919
1909
return fetches .build ();
1920
1910
}
1921
1911
1912
+ private boolean skipFetchable (Fetchable fetchable , FetchTiming fetchTiming ) {
1913
+ if ( fetchable .asBasicValuedModelPart () != null ) {
1914
+ // Ignore lazy basic columns
1915
+ return fetchTiming == FetchTiming .DELAYED ;
1916
+ }
1917
+ else if ( fetchable instanceof Association ) {
1918
+ final Association association = (Association ) fetchable ;
1919
+ // Ignore the fetchable if the FK is on the other side
1920
+ return association .getSideNature () == ForeignKeyDescriptor .Nature .TARGET
1921
+ // Ensure the FK comes from the root table
1922
+ || !getRootTableName ().equals ( association .getForeignKeyDescriptor ().getKeyTable () );
1923
+ }
1924
+ else {
1925
+ return false ;
1926
+ }
1927
+ }
1928
+
1922
1929
/**
1923
1930
* @deprecated use {@link Fetchable#isSelectable()} instead.
1924
1931
*/
@@ -5907,7 +5914,7 @@ public Fetchable getKeyFetchable(int position) {
5907
5914
}
5908
5915
5909
5916
@ Override
5910
- public Fetchable getFetchable (int position ) {
5917
+ public AttributeMapping getFetchable (int position ) {
5911
5918
return getStaticFetchableList ().get ( position );
5912
5919
}
5913
5920
0 commit comments