@@ -165,22 +165,21 @@ private void handleAliases(String token, StringBuilder result) {
165
165
}
166
166
else {
167
167
final String aliasName = token .substring ( 0 , firstDot );
168
+ final String propertyName = token .substring ( firstDot + 1 );
168
169
if ( context .isCollectionAlias ( aliasName ) ) {
169
170
// 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 ) );
172
172
aliasesFound ++;
173
173
}
174
174
else if ( context .isEntityAlias ( aliasName ) ) {
175
175
// 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 ) );
178
177
aliasesFound ++;
179
178
}
180
179
else {
181
180
// passing through anything we do not know
182
181
// to support jdbc escape sequences HB-898
183
- result .append ( '{' ).append (token ).append ( '}' );
182
+ result .append ( '{' ).append ( token ).append ( '}' );
184
183
}
185
184
}
186
185
}
@@ -217,42 +216,48 @@ private void handlePlaceholder(String token, StringBuilder result) {
217
216
}
218
217
}
219
218
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 );
225
222
final String collectionSuffix = context .getCollectionSuffix ( aliasName );
226
223
switch ( propertyName ) {
227
224
case "*" :
228
225
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
+ );
230
231
}
231
232
aliasesFound ++;
232
233
return collectionPersister .selectFragment ( aliasName , collectionSuffix )
233
- + ", " + resolveProperties ( aliasName , propertyName );
234
+ + ", " + resolveProperties ( aliasName , propertyName , token );
234
235
case "element.*" :
235
- return resolveProperties ( aliasName , "*" );
236
+ return resolveProperties ( aliasName , "*" , token );
236
237
default :
237
238
// Let return-properties override whatever the persister has for aliases.
238
239
String [] columnAliases = fieldResults .get ( propertyName );
239
240
if ( columnAliases == null ) {
240
241
columnAliases =
241
242
collectionPersister .getCollectionPropertyColumnAliases ( propertyName , collectionSuffix );
242
243
}
243
- validate ( aliasName , propertyName , columnAliases );
244
+ validate ( aliasName , propertyName , columnAliases , token );
244
245
aliasesFound ++;
245
246
return columnAliases [0 ];
246
247
}
247
248
}
248
249
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 );
252
253
final String suffix = context .getEntitySuffix ( aliasName );
253
254
if ( "*" .equals ( propertyName ) ) {
254
255
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
+ );
256
261
}
257
262
aliasesFound ++;
258
263
return persister .selectFragment ( aliasName , suffix ) ;
@@ -263,24 +268,24 @@ private String resolveProperties(String aliasName, String propertyName) {
263
268
if ( columnAliases == null ) {
264
269
columnAliases = persister .getSubclassPropertyColumnAliases ( propertyName , suffix );
265
270
}
266
- validate ( aliasName , propertyName , columnAliases );
271
+ validate ( aliasName , propertyName , columnAliases , token );
267
272
aliasesFound ++;
268
273
return columnAliases [0 ];
269
274
}
270
275
}
271
276
272
- private void validate (String aliasName , String propertyName , String [] columnAliases ) {
277
+ private void validate (String aliasName , String propertyName , String [] columnAliases , String token ) {
273
278
if ( columnAliases == null || columnAliases .length == 0 ) {
274
279
throw new QueryException (
275
- "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]" ,
280
+ "No column for interpolation '%s'"
281
+ .formatted ( token ),
276
282
originalQueryString
277
283
);
278
284
}
279
285
if ( columnAliases .length != 1 ) {
280
- // TODO: better error message since we actually support composites if names are explicitly listed
281
286
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 ) ,
284
289
originalQueryString
285
290
);
286
291
}
0 commit comments