diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java index dc03478ddb66..97bd9d3e8e4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java @@ -36,7 +36,6 @@ import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.KeyedPage; import org.hibernate.query.KeyedResultList; -import org.hibernate.query.QueryFlushMode; import org.hibernate.query.QueryParameter; import org.hibernate.query.ResultListTransformer; import org.hibernate.query.TupleTransformer; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java index ed20046535b7..0ed5efced51c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ResultSetMappingProcessor.java @@ -14,7 +14,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; -import org.hibernate.MappingException; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.internal.AliasConstantsHelper; import org.hibernate.metamodel.mapping.EntityMappingType; @@ -78,32 +77,11 @@ public class ResultSetMappingProcessor implements SQLQueryParser.ParserContext { private int entitySuffixSeed; private int collectionSuffixSeed; - public ResultSetMappingProcessor(ResultSetMapping resultSetMapping, SessionFactoryImplementor factory) { this.resultSetMapping = resultSetMapping; this.factory = factory; } - private Map internalGetPropertyResultsMap(String alias) { - final Map propertyResultMap = getPropertyResultMap( alias ); - if ( propertyResultMap != null ) { - return propertyResultMap; - } - else { - final NativeQuery.ResultNode resultNode = alias2Return.get( alias ); - return resultNode instanceof NativeQuery.ReturnProperty - && !( resultNode instanceof NativeQuery.FetchReturn ) - ? null - // todo (6.0): access property results map somehow which was on NativeSQLQueryNonScalarReturn before - : emptyMap(); - } - } - - private Map getPropertyResultMap(String alias) { - final Map propertyResultMap = collectionPropertyResultMaps.get( alias ); - return propertyResultMap == null ? entityPropertyResultMaps.get( alias ) : propertyResultMap; - } - public SQLQueryParser.ParserContext process() { // first, break down the returns into maps keyed by alias // so that role returns can be more easily resolved to their owners @@ -115,24 +93,24 @@ public SQLQueryParser.ParserContext process() { } else if ( resultBuilder instanceof NativeQuery.CollectionReturn collectionReturn ) { alias2Return.put( collectionReturn.getTableAlias(), collectionReturn ); - Map propertyResultsMap = emptyMap(); //fetchReturn.getPropertyResultsMap() addCollection( collectionReturn.getNavigablePath().getFullPath(), collectionReturn.getTableAlias(), - propertyResultsMap + emptyMap() //fetchReturn.getPropertyResultsMap() ); } } ); // handle fetches defined using {@code hbm.xml} or NativeQuery apis - resultSetMapping.visitLegacyFetchBuilders( (fetchBuilder) -> { - alias2Return.put( fetchBuilder.getTableAlias(), (NativeQuery.ReturnableResultNode) fetchBuilder ); + resultSetMapping.visitLegacyFetchBuilders( fetchBuilder -> { + alias2Return.put( fetchBuilder.getTableAlias(), + (NativeQuery.ReturnableResultNode) fetchBuilder ); alias2OwnerAlias.put( fetchBuilder.getTableAlias(), fetchBuilder.getOwnerAlias() ); } ); // Now, process the returns - for ( NativeQuery.ResultNode queryReturn : alias2Return.values() ) { + for ( var queryReturn : alias2Return.values() ) { processReturn( queryReturn ); } @@ -152,10 +130,12 @@ else if ( fetchBuilder instanceof NativeQuery.FetchReturn fetchReturn ) { public ResultSetMapping generateResultMapping(boolean queryHadAliases) { if ( queryHadAliases ) { - final ResultSetMapping mapping = resolveResultSetMapping( null, false, factory ); + final var mapping = resolveResultSetMapping( null, false, factory ); final Set visited = new HashSet<>(); - resultSetMapping.visitResultBuilders( (i, builder) -> visitResultSetBuilder( builder, visited, mapping ) ); - resultSetMapping.visitLegacyFetchBuilders( builder -> applyFetchBuilder( mapping, builder, visited ) ); + resultSetMapping.visitResultBuilders( (i, builder) + -> visitResultSetBuilder( mapping, builder, visited ) ); + resultSetMapping.visitLegacyFetchBuilders( builder + -> applyFetchBuilder( mapping, builder, visited ) ); return mapping; } else { @@ -164,7 +144,10 @@ public ResultSetMapping generateResultMapping(boolean queryHadAliases) { } - private void visitResultSetBuilder(ResultBuilder resultBuilder, Set visited, ResultSetMapping resultSetMapping) { + private void visitResultSetBuilder( + ResultSetMapping resultSetMapping, + ResultBuilder resultBuilder, + Set visited) { if ( resultBuilder instanceof NativeQuery.RootReturn rootReturn ) { final String suffix = alias2Suffix.get( rootReturn.getTableAlias() ); visited.add( rootReturn.getTableAlias() ); @@ -172,8 +155,7 @@ private void visitResultSetBuilder(ResultBuilder resultBuilder, Set visi resultSetMapping.addResultBuilder( resultBuilder ); } else { - final DynamicResultBuilderEntityStandard resultBuilderEntity = - createSuffixedResultBuilder( rootReturn, suffix ); + final var resultBuilderEntity = createSuffixedResultBuilder( rootReturn, suffix ); resultSetMapping.addResultBuilder( resultBuilderEntity ); alias2Return.put( rootReturn.getTableAlias(), resultBuilderEntity ); } @@ -184,10 +166,9 @@ else if ( resultBuilder instanceof NativeQuery.CollectionReturn collectionReturn resultSetMapping.addResultBuilder( resultBuilder ); } else { - final CompleteResultBuilderCollectionStandard resultBuilderCollection = + final var resultBuilderCollection = createSuffixedResultBuilder( collectionReturn, suffix, alias2Suffix.get( collectionReturn.getTableAlias() ) ); - resultSetMapping.addResultBuilder( resultBuilderCollection ); alias2Return.put( collectionReturn.getTableAlias(), resultBuilderCollection ); } @@ -214,20 +195,26 @@ private void applyFetchBuilder( applyFetchBuilder( resultSetMapping, // At this point, only legacy fetch builders weren't visited - (DynamicFetchBuilderLegacy) alias2Return.get( fetchBuilder.getOwnerAlias() ), + (DynamicFetchBuilderLegacy) + alias2Return.get( fetchBuilder.getOwnerAlias() ), visited ); } - // At this point, the owner builder must be a DynamicResultBuilderEntityStandard to which we can add this builder - final DynamicResultBuilderEntityStandard ownerBuilder = - (DynamicResultBuilderEntityStandard) alias2Return.get( fetchBuilder.getOwnerAlias() ); - final DynamicResultBuilderEntityStandard resultBuilderEntity = createSuffixedResultBuilder( - alias2Persister.get( fetchBuilder.getTableAlias() ).findContainingEntityMapping(), - fetchBuilder.getTableAlias(), - suffix, - null, - determineNavigablePath( fetchBuilder ) - ); + // At this point, the owner builder must be a + // DynamicResultBuilderEntityStandard to which + // we can add this builder + final var ownerBuilder = + (DynamicResultBuilderEntityStandard) + alias2Return.get( fetchBuilder.getOwnerAlias() ); + final var resultBuilderEntity = + createSuffixedResultBuilder( + alias2Persister.get( fetchBuilder.getTableAlias() ) + .findContainingEntityMapping(), + fetchBuilder.getTableAlias(), + suffix, + null, + determineNavigablePath( fetchBuilder ) + ); ownerBuilder.addFetchBuilder( fetchBuilder.getFetchable(), new DynamicFetchBuilderLegacy( @@ -245,25 +232,23 @@ private void applyFetchBuilder( } private List columnNames( - DynamicResultBuilderEntityStandard resultBuilder, LegacyFetchBuilder fetchBuilder) { + DynamicResultBuilderEntityStandard resultBuilder, + LegacyFetchBuilder fetchBuilder) { final String[] columnAliases = alias2Persister.get( fetchBuilder.getOwnerAlias() ) .getSubclassPropertyColumnAliases( fetchBuilder.getFetchable().getFetchableName(), alias2Suffix.get( fetchBuilder.getOwnerAlias() ) ); if ( columnAliases.length == 0 ) { - final CollectionPersister collectionPersister = - alias2CollectionPersister.get( fetchBuilder.getTableAlias() ); + final var collectionPersister = alias2CollectionPersister.get( fetchBuilder.getTableAlias() ); if ( collectionPersister == null ) { return emptyList(); } else { final String collectionSuffix = alias2CollectionSuffix.get( fetchBuilder.getTableAlias() ); if ( collectionPersister.hasIndex() ) { - final PluralAttributeMapping fetchable = (PluralAttributeMapping) fetchBuilder.getFetchable(); - resultBuilder.addProperty( - fetchable.getIndexDescriptor(), - collectionPersister.getIndexColumnAliases( collectionSuffix ) - ); + final var fetchable = (PluralAttributeMapping) fetchBuilder.getFetchable(); + resultBuilder.addProperty( fetchable.getIndexDescriptor(), + collectionPersister.getIndexColumnAliases( collectionSuffix ) ); } return asList( collectionPersister.getKeyColumnAliases( collectionSuffix ) ); } @@ -274,7 +259,7 @@ private List columnNames( } private NavigablePath determineNavigablePath(LegacyFetchBuilder fetchBuilder) { - final NativeQuery.ResultNode ownerResult = alias2Return.get( fetchBuilder.getOwnerAlias() ); + final var ownerResult = alias2Return.get( fetchBuilder.getOwnerAlias() ); final NavigablePath path; if ( ownerResult instanceof NativeQuery.RootReturn rootReturn ) { path = rootReturn.getNavigablePath(); @@ -296,7 +281,8 @@ private DynamicResultBuilderEntityStandard createSuffixedResultBuilder( rootReturn.getTableAlias(), suffix, rootReturn.getLockMode(), - new NavigablePath( rootReturn.getEntityMapping().getEntityName(), rootReturn.getTableAlias() ) + new NavigablePath( rootReturn.getEntityMapping().getEntityName(), + rootReturn.getTableAlias() ) ); } @@ -306,32 +292,32 @@ private DynamicResultBuilderEntityStandard createSuffixedResultBuilder( String suffix, LockMode lockMode, NavigablePath navigablePath) { - final EntityPersister loadable = entityMapping.getEntityPersister(); - final DynamicResultBuilderEntityStandard resultBuilderEntity = + final var resultBuilderEntity = new DynamicResultBuilderEntityStandard( entityMapping, tableAlias, navigablePath ); resultBuilderEntity.setLockMode( lockMode ); - final String[] identifierAliases = loadable.getIdentifierAliases( suffix ); + final var persister = entityMapping.getEntityPersister(); + final String[] identifierAliases = persister.getIdentifierAliases( suffix ); resultBuilderEntity.addIdColumnAliases( identifierAliases ); - resultBuilderEntity.setDiscriminatorAlias( loadable.getDiscriminatorAlias( suffix ) ); - if ( loadable.hasIdentifierProperty() ) { - resultBuilderEntity.addProperty( loadable.getIdentifierMapping(), identifierAliases ); + resultBuilderEntity.setDiscriminatorAlias( persister.getDiscriminatorAlias( suffix ) ); + if ( persister.hasIdentifierProperty() ) { + resultBuilderEntity.addProperty( persister.getIdentifierMapping(), identifierAliases ); } - loadable.visitFetchables( + persister.visitFetchables( (index, fetchable) -> { if ( fetchable.isSelectable() ) { addFetchBuilder( suffix, - loadable, + persister, resultBuilderEntity, tableAlias, identifierAliases, fetchable, - loadable.getSubclassPropertyColumnAliases( fetchable.getFetchableName(), suffix ), - loadable instanceof SingleTableEntityPersister singleTableEntityPersister + persister.getSubclassPropertyColumnAliases( fetchable.getFetchableName(), suffix ), + persister instanceof SingleTableEntityPersister singleTableEntityPersister ? singleTableEntityPersister.getSubclassPropertyType( index ) - : loadable.getPropertyType( fetchable.getFetchableName() ) + : persister.getPropertyType( fetchable.getFetchableName() ) ); } }, @@ -357,7 +343,7 @@ private void addFetchBuilder( resultBuilderEntity.addProperty( fetchable, keyColumnAliases ); } else if ( propertyType instanceof ComponentType componentType ) { - final DynamicFetchBuilderLegacy fetchBuilder = new DynamicFetchBuilderLegacy( + final var fetchBuilder = new DynamicFetchBuilderLegacy( "", tableAlias, fetchable, @@ -368,7 +354,8 @@ else if ( propertyType instanceof ComponentType componentType ) { final Type[] propertyTypes = componentType.getSubtypes(); int aliasIndex = 0; for ( int i = 0; i < propertyNames.length; i++ ) { - final int columnSpan = propertyTypes[i].getColumnSpan( loadable.getFactory().getRuntimeMetamodels() ); + final Type type = propertyTypes[i]; + final int columnSpan = type.getColumnSpan( loadable.getFactory().getRuntimeMetamodels() ); addFetchBuilder( suffix, loadable, @@ -377,7 +364,7 @@ else if ( propertyType instanceof ComponentType componentType ) { identifierAliases, fetchable, slice( columnAliases, aliasIndex, columnSpan ), - propertyTypes[i] + type ); aliasIndex += columnSpan; } @@ -386,7 +373,7 @@ else if ( propertyType instanceof ComponentType componentType ) { } else if ( columnAliases.length != 0 ) { if ( propertyType instanceof EntityType ) { - final ToOneAttributeMapping toOne = (ToOneAttributeMapping) fetchable; + final var toOne = (ToOneAttributeMapping) fetchable; if ( !toOne.getIdentifyingColumnsTableExpression().equals( loadable.getTableName() ) ) { // The to-one has a join-table, use the plain join column name instead of the alias assert columnAliases.length == 1; @@ -404,7 +391,7 @@ private CompleteResultBuilderCollectionStandard createSuffixedResultBuilder( NativeQuery.CollectionReturn collectionReturn, String suffix, String entitySuffix) { - final CollectionPersister collectionPersister = collectionReturn.getPluralAttribute().getCollectionDescriptor(); + final var collectionPersister = collectionReturn.getPluralAttribute().getCollectionDescriptor(); return new CompleteResultBuilderCollectionStandard( collectionReturn.getTableAlias(), collectionReturn.getNavigablePath(), @@ -419,14 +406,15 @@ private CompleteResultBuilderCollectionStandard createSuffixedResultBuilder( private static String[] getElementColumnAliases( String suffix, String entitySuffix, CollectionPersister collectionPersister) { - if ( collectionPersister.getElementType() instanceof EntityType ) { - final EntityPersister elementPersister = collectionPersister.getElementPersister(); + if ( collectionPersister.getElementType().isEntityType() ) { + final var elementPersister = collectionPersister.getElementPersister(); final String[] propertyNames = elementPersister.getPropertyNames(); final String[] identifierAliases = elementPersister.getIdentifierAliases( entitySuffix ); final String discriminatorAlias = elementPersister.getDiscriminatorAlias( entitySuffix ); - final List aliases = new ArrayList<>( - propertyNames.length + identifierAliases.length + ( discriminatorAlias == null ? 0 : 1 ) - ); + final int size = + propertyNames.length + identifierAliases.length + + (discriminatorAlias == null ? 0 : 1); + final List aliases = new ArrayList<>( size ); addAll( aliases, identifierAliases ); if ( discriminatorAlias != null ) { aliases.add( discriminatorAlias ); @@ -441,10 +429,6 @@ private static String[] getElementColumnAliases( } } - private EntityPersister getSQLLoadable(String entityName) throws MappingException { - return factory.getMappingMetamodel().getEntityDescriptor( entityName ); - } - private String generateEntitySuffix() { return AliasConstantsHelper.get( entitySuffixSeed++ ); } @@ -489,9 +473,11 @@ private void processScalarReturn(NativeQuery.ReturnProperty typeReturn) { private void processRootReturn(NativeQuery.RootReturn rootReturn) { if ( !alias2Persister.containsKey( rootReturn.getTableAlias() ) ) { - final EntityPersister persister = rootReturn.getEntityMapping().getEntityPersister(); - final Map propertyResultsMap = emptyMap(); //rootReturn.getPropertyResultsMap() - addPersister( rootReturn.getTableAlias(), propertyResultsMap, persister ); + addPersister( + rootReturn.getTableAlias(), + emptyMap(), //rootReturn.getPropertyResultsMap(), + rootReturn.getEntityMapping().getEntityPersister() + ); } // else already processed } @@ -503,26 +489,29 @@ private void addPersister(String alias, Map propertyResult, En } private void addCollection(String role, String alias, Map propertyResults) { - - final CollectionPersister collectionDescriptor = - factory.getMappingMetamodel().getCollectionDescriptor( role ); - + final var collectionDescriptor = + factory.getMappingMetamodel() + .getCollectionDescriptor( role ); alias2CollectionPersister.put( alias, collectionDescriptor ); alias2CollectionSuffix.put( alias, generateCollectionSuffix() ); collectionPropertyResultMaps.put( alias, propertyResults ); - if ( collectionDescriptor.isOneToMany() || collectionDescriptor.isManyToMany() ) { - addPersister( alias, filter( propertyResults ), collectionDescriptor.getElementPersister() ); + addPersister( + alias, + filter( propertyResults ), + collectionDescriptor.getElementPersister() + ); } } private Map filter(Map propertyResults) { final Map result = new HashMap<>( propertyResults.size() ); final String keyPrefix = "element."; - for ( Map.Entry element : propertyResults.entrySet() ) { + for ( var element : propertyResults.entrySet() ) { final String path = element.getKey(); if ( path.startsWith( keyPrefix ) ) { - result.put( path.substring( keyPrefix.length() ), element.getValue() ); + result.put( path.substring( keyPrefix.length() ), + element.getValue() ); } } return result; @@ -543,19 +532,24 @@ private void processFetchReturn(NativeQuery.FetchReturn fetchReturn) { processReturn( alias2Return.get( ownerAlias ) ); } - final EntityPersister ownerPersister = alias2Persister.get( ownerAlias ); - final Type returnType = ownerPersister.getPropertyType( fetchReturn.getFetchable().getFetchableName() ); + final var ownerPersister = alias2Persister.get( ownerAlias ); + final String fetchableName = fetchReturn.getFetchable().getFetchableName(); + final Type returnType = ownerPersister.getPropertyType( fetchableName ); if ( returnType instanceof CollectionType ) { - final String role = ownerPersister.getEntityName() + '.' + fetchReturn.getFetchable().getFetchableName(); - final Map propertyResultsMap = emptyMap(); //fetchReturn.getPropertyResultsMap() - addCollection( role, alias, propertyResultsMap ); + addCollection( + ownerPersister.getEntityName() + '.' + fetchableName, + alias, + emptyMap() //fetchReturn.getPropertyResultsMap() + ); // collectionOwnerAliases.add( ownerAlias ); } else if ( returnType instanceof EntityType entityType ) { - final String returnEntityName = entityType.getAssociatedEntityName(); - final EntityPersister persister = getSQLLoadable( returnEntityName ); - final Map propertyResultsMap = emptyMap(); //fetchReturn.getPropertyResultsMap() - addPersister( alias, propertyResultsMap, persister ); + addPersister( + alias, + emptyMap(), //fetchReturn.getPropertyResultsMap() + factory.getMappingMetamodel() + .getEntityDescriptor( entityType.getAssociatedEntityName() ) + ); } } // else already processed @@ -597,7 +591,21 @@ public String getOwnerAlias(String alias) { @Override public Map getPropertyResultsMap(String alias) { - return internalGetPropertyResultsMap( alias ); + final var collectionMap = collectionPropertyResultMaps.get( alias ); + if ( collectionMap != null ) { + return collectionMap; + } + final var entityMap = entityPropertyResultMaps.get( alias ); + if ( entityMap != null ) { + return entityMap; + } + + final var resultNode = alias2Return.get( alias ); + return resultNode instanceof NativeQuery.ReturnProperty + && !( resultNode instanceof NativeQuery.FetchReturn ) + ? null + // todo (6.0): access property results map somehow which was on NativeSQLQueryNonScalarReturn before + : emptyMap(); } // public String[] collectQuerySpaces() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java index f5955adf0737..3e58e4298947 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/SQLQueryParser.java @@ -160,22 +160,21 @@ private void handleAliases(String token, StringBuilder result) { } else { final String aliasName = token.substring( 0, firstDot ); + final String propertyName = token.substring( firstDot + 1 ); if ( context.isCollectionAlias( aliasName ) ) { // The current alias is referencing the collection to be eagerly fetched - String propertyName = token.substring( firstDot + 1 ); - result.append( resolveCollectionProperties( aliasName, propertyName ) ); + result.append( resolveCollectionProperties( aliasName, propertyName, token ) ); aliasesFound++; } else if ( context.isEntityAlias( aliasName ) ) { // it is a property reference {foo.bar} - String propertyName = token.substring( firstDot + 1 ); - result.append( resolveProperties( aliasName, propertyName ) ); + result.append( resolveProperties( aliasName, propertyName, token ) ); aliasesFound++; } else { // passing through anything we do not know // to support jdbc escape sequences HB-898 - result.append( '{' ).append(token).append( '}' ); + result.append( '{' ).append( token ).append( '}' ); } } } @@ -212,22 +211,24 @@ private void handlePlaceholder(String token, StringBuilder result) { } } - private String resolveCollectionProperties( - String aliasName, - String propertyName) { - final Map fieldResults = context.getPropertyResultsMap( aliasName ); - final CollectionPersister collectionPersister = context.getCollectionPersister( aliasName ); + private String resolveCollectionProperties(String aliasName, String propertyName, String token) { + final var fieldResults = context.getPropertyResultsMap( aliasName ); + final var collectionPersister = context.getCollectionPersister( aliasName ); final String collectionSuffix = context.getCollectionSuffix( aliasName ); switch ( propertyName ) { case "*": if ( !fieldResults.isEmpty() ) { - throw new QueryException( "Using return-property together with * syntax is not supported" ); + throw new QueryException( + "Illegal interpolation '%s' ('%s' is a field alias)" + .formatted( token, aliasName ), + originalQueryString + ); } aliasesFound++; return collectionPersister.selectFragment( aliasName, collectionSuffix ) - + ", " + resolveProperties( aliasName, propertyName ); + + ", " + resolveProperties( aliasName, propertyName, token ); case "element.*": - return resolveProperties( aliasName, "*" ); + return resolveProperties( aliasName, "*", token ); default: // Let return-properties override whatever the persister has for aliases. String[] columnAliases = fieldResults.get( propertyName ); @@ -235,19 +236,23 @@ private String resolveCollectionProperties( columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix ); } - validate( aliasName, propertyName, columnAliases ); + validate( aliasName, propertyName, columnAliases, token ); aliasesFound++; return columnAliases[0]; } } - private String resolveProperties(String aliasName, String propertyName) { - final Map fieldResults = context.getPropertyResultsMap( aliasName ); - final EntityPersister persister = context.getEntityPersister( aliasName ); + private String resolveProperties(String aliasName, String propertyName, String token) { + final var fieldResults = context.getPropertyResultsMap( aliasName ); + final var persister = context.getEntityPersister( aliasName ); final String suffix = context.getEntitySuffix( aliasName ); if ( "*".equals( propertyName ) ) { if ( !fieldResults.isEmpty() ) { - throw new QueryException( "Using return-property together with * syntax is not supported" ); + throw new QueryException( + "Illegal interpolation '%s' ('%s' is a field alias)" + .formatted( token, aliasName ), + originalQueryString + ); } aliasesFound++; return persister.selectFragment( aliasName, suffix ) ; @@ -258,24 +263,24 @@ private String resolveProperties(String aliasName, String propertyName) { if ( columnAliases == null ) { columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix ); } - validate( aliasName, propertyName, columnAliases ); + validate( aliasName, propertyName, columnAliases, token ); aliasesFound++; return columnAliases[0]; } } - private void validate(String aliasName, String propertyName, String[] columnAliases) { + private void validate(String aliasName, String propertyName, String[] columnAliases, String token) { if ( columnAliases == null || columnAliases.length == 0 ) { throw new QueryException( - "No column name found for property [" + propertyName + "] for alias [" + aliasName + "]", + "No column for interpolation '%s'" + .formatted( token ), originalQueryString ); } if ( columnAliases.length != 1 ) { - // TODO: better error message since we actually support composites if names are explicitly listed throw new QueryException( - "SQL queries only support properties mapped to a single column - property [" + - propertyName + "] is mapped to " + columnAliases.length + " columns.", + "Multiple columns for interpolation '%s' ('%s' is mapped to %s columns)" + .formatted( token, propertyName, columnAliases.length ), originalQueryString ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java index 26a874c1629a..37769a063e4b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/javatime/GlobalJavaTimeJdbcTypeTests.java @@ -50,7 +50,6 @@ * * @author Steve Ebersole */ -@SuppressWarnings("JUnitMalformedDeclaration") @ServiceRegistry( settings = @Setting(name = MappingSettings.JAVA_TIME_USE_DIRECT_JDBC, value = "true") )