@@ -165,22 +165,21 @@ private void handleAliases(String token, StringBuilder result) {
165165 }
166166 else {
167167 final String aliasName = token .substring ( 0 , firstDot );
168+ final String propertyName = token .substring ( firstDot + 1 );
168169 if ( context .isCollectionAlias ( aliasName ) ) {
169170 // The current alias is referencing the collection to be eagerly fetched
170- String propertyName = token .substring ( firstDot + 1 );
171- result .append ( resolveCollectionProperties ( aliasName , propertyName ) );
171+ result .append ( resolveCollectionProperties ( aliasName , propertyName , token ) );
172172 aliasesFound ++;
173173 }
174174 else if ( context .isEntityAlias ( aliasName ) ) {
175175 // it is a property reference {foo.bar}
176- String propertyName = token .substring ( firstDot + 1 );
177- result .append ( resolveProperties ( aliasName , propertyName ) );
176+ result .append ( resolveProperties ( aliasName , propertyName , token ) );
178177 aliasesFound ++;
179178 }
180179 else {
181180 // passing through anything we do not know
182181 // to support jdbc escape sequences HB-898
183- result .append ( '{' ).append (token ).append ( '}' );
182+ result .append ( '{' ).append ( token ).append ( '}' );
184183 }
185184 }
186185 }
@@ -217,42 +216,48 @@ private void handlePlaceholder(String token, StringBuilder result) {
217216 }
218217 }
219218
220- private String resolveCollectionProperties (
221- String aliasName ,
222- String propertyName ) {
223- final Map <String , String []> fieldResults = context .getPropertyResultsMap ( aliasName );
224- final CollectionPersister collectionPersister = context .getCollectionPersister ( aliasName );
219+ private String resolveCollectionProperties (String aliasName , String propertyName , String token ) {
220+ final var fieldResults = context .getPropertyResultsMap ( aliasName );
221+ final var collectionPersister = context .getCollectionPersister ( aliasName );
225222 final String collectionSuffix = context .getCollectionSuffix ( aliasName );
226223 switch ( propertyName ) {
227224 case "*" :
228225 if ( !fieldResults .isEmpty () ) {
229- throw new QueryException ( "Using return-property together with * syntax is not supported" );
226+ throw new QueryException (
227+ "Illegal interpolation '%s' ('%s' is a field alias)"
228+ .formatted ( token , aliasName ),
229+ originalQueryString
230+ );
230231 }
231232 aliasesFound ++;
232233 return collectionPersister .selectFragment ( aliasName , collectionSuffix )
233- + ", " + resolveProperties ( aliasName , propertyName );
234+ + ", " + resolveProperties ( aliasName , propertyName , token );
234235 case "element.*" :
235- return resolveProperties ( aliasName , "*" );
236+ return resolveProperties ( aliasName , "*" , token );
236237 default :
237238 // Let return-properties override whatever the persister has for aliases.
238239 String [] columnAliases = fieldResults .get ( propertyName );
239240 if ( columnAliases == null ) {
240241 columnAliases =
241242 collectionPersister .getCollectionPropertyColumnAliases ( propertyName , collectionSuffix );
242243 }
243- validate ( aliasName , propertyName , columnAliases );
244+ validate ( aliasName , propertyName , columnAliases , token );
244245 aliasesFound ++;
245246 return columnAliases [0 ];
246247 }
247248 }
248249
249- private String resolveProperties (String aliasName , String propertyName ) {
250- final Map < String , String []> fieldResults = context .getPropertyResultsMap ( aliasName );
251- final EntityPersister persister = context .getEntityPersister ( aliasName );
250+ private String resolveProperties (String aliasName , String propertyName , String token ) {
251+ final var fieldResults = context .getPropertyResultsMap ( aliasName );
252+ final var persister = context .getEntityPersister ( aliasName );
252253 final String suffix = context .getEntitySuffix ( aliasName );
253254 if ( "*" .equals ( propertyName ) ) {
254255 if ( !fieldResults .isEmpty () ) {
255- throw new QueryException ( "Using return-property together with * syntax is not supported" );
256+ throw new QueryException (
257+ "Illegal interpolation '%s' ('%s' is a field alias)"
258+ .formatted ( token , aliasName ),
259+ originalQueryString
260+ );
256261 }
257262 aliasesFound ++;
258263 return persister .selectFragment ( aliasName , suffix ) ;
@@ -263,24 +268,24 @@ private String resolveProperties(String aliasName, String propertyName) {
263268 if ( columnAliases == null ) {
264269 columnAliases = persister .getSubclassPropertyColumnAliases ( propertyName , suffix );
265270 }
266- validate ( aliasName , propertyName , columnAliases );
271+ validate ( aliasName , propertyName , columnAliases , token );
267272 aliasesFound ++;
268273 return columnAliases [0 ];
269274 }
270275 }
271276
272- private void validate (String aliasName , String propertyName , String [] columnAliases ) {
277+ private void validate (String aliasName , String propertyName , String [] columnAliases , String token ) {
273278 if ( columnAliases == null || columnAliases .length == 0 ) {
274279 throw new QueryException (
275- "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]" ,
280+ "No column for interpolation '%s'"
281+ .formatted ( token ),
276282 originalQueryString
277283 );
278284 }
279285 if ( columnAliases .length != 1 ) {
280- // TODO: better error message since we actually support composites if names are explicitly listed
281286 throw new QueryException (
282- "SQL queries only support properties mapped to a single column - property [" +
283- propertyName + "] is mapped to " + columnAliases .length + " columns." ,
287+ "Multiple columns for interpolation '%s' ('%s' is mapped to %s columns)"
288+ . formatted ( token , propertyName , columnAliases .length ) ,
284289 originalQueryString
285290 );
286291 }
0 commit comments