From c24797b0e38682ac3f1312a25203eb9a39987e6e Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Thu, 23 Jul 2026 14:44:14 +0200 Subject: [PATCH 1/2] HHH-20716 Add test for issue --- .../hibernate/orm/test/hqlimport/Animal.java | 26 +++++++++ .../org/hibernate/orm/test/hqlimport/Cat.java | 17 ++++++ .../org/hibernate/orm/test/hqlimport/Dog.java | 17 ++++++ .../orm/test/hqlimport/HqlImportTest.java | 54 +++++++++++++++++++ .../orm/test/hqlimport/Mappings.orm.xml | 38 +++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Animal.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Cat.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Dog.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/HqlImportTest.java create mode 100644 hibernate-core/src/test/resources/org/hibernate/orm/test/hqlimport/Mappings.orm.xml diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Animal.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Animal.java new file mode 100644 index 000000000000..e455adc1a4a0 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Animal.java @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.hqlimport; + +public class Animal { + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Cat.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Cat.java new file mode 100644 index 000000000000..4c8b175b71e3 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Cat.java @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.hqlimport; + +public class Cat extends Animal { + private boolean indoor; + + public boolean isIndoor() { + return indoor; + } + + public void setIndoor(boolean indoor) { + this.indoor = indoor; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Dog.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Dog.java new file mode 100644 index 000000000000..dee0888ac7d4 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/Dog.java @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.hqlimport; + +public class Dog extends Animal { + private String breed; + + public String getBreed() { + return breed; + } + + public void setBreed(String breed) { + this.breed = breed; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/HqlImportTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/HqlImportTest.java new file mode 100644 index 000000000000..70c7442b9ec6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/hqlimport/HqlImportTest.java @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.hqlimport; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Verifies that {@code } (hql-import) elements in orm.xml are processed + * and register class names for use in HQL polymorphic queries. + */ +@JiraKey("HHH-20716") +@DomainModel(xmlMappings = "org/hibernate/orm/test/hqlimport/Mappings.orm.xml") +@SessionFactory +public class HqlImportTest { + + @AfterEach + void tearDown(SessionFactoryScope scope) { + scope.getSessionFactory().getSchemaManager().truncate(); + } + + @Test + void testPolymorphicQueryUsingImportedName(SessionFactoryScope scope) { + scope.inTransaction( session -> { + Dog dog = new Dog(); + dog.setName( "Rex" ); + dog.setBreed( "Labrador" ); + session.persist( dog ); + + Cat cat = new Cat(); + cat.setName( "Whiskers" ); + cat.setIndoor( true ); + session.persist( cat ); + } ); + + scope.inTransaction( session -> { + // "Animal" is not an entity — it's imported via + // so it can be used as an HQL name for polymorphic queries + List animals = session.createQuery( "from Animal", Animal.class ).list(); + assertThat( animals ).hasSize( 2 ); + assertThat( animals ).extracting( Animal::getName ).containsExactlyInAnyOrder( "Rex", "Whiskers" ); + } ); + } +} diff --git a/hibernate-core/src/test/resources/org/hibernate/orm/test/hqlimport/Mappings.orm.xml b/hibernate-core/src/test/resources/org/hibernate/orm/test/hqlimport/Mappings.orm.xml new file mode 100644 index 000000000000..45e6563d7724 --- /dev/null +++ b/hibernate-core/src/test/resources/org/hibernate/orm/test/hqlimport/Mappings.orm.xml @@ -0,0 +1,38 @@ + + + + org.hibernate.orm.test.hqlimport + property + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + From 23007c7befa2efeb5c380832726a314f584bc1b1 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 22 Jul 2026 16:26:06 +0200 Subject: [PATCH 2/2] HHH-20716 Process hql-import elements from orm xml mappings The elements in orm.xml were parsed into the JAXB model but never processed. This adds collection of hql-imports during XML processing (in DomainModelCategorizationCollector) and applies them as imports during processQueryRenames() in the annotation processor. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../AnnotationMetadataSourceProcessorImpl.java | 4 ++++ .../internal/DomainModelCategorizationCollector.java | 3 +++ .../models/internal/GlobalRegistrationsImpl.java | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java index 299d57118ce6..62484c9f495a 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java @@ -134,6 +134,10 @@ public void processTypeDefinitions() { @Override public void processQueryRenames() { + final var importedRenames = domainModelSource.getGlobalRegistrations().getImportedRenames(); + for ( var entry : importedRenames.entrySet() ) { + rootMetadataBuildingContext.getMetadataCollector().addImport( entry.getKey(), entry.getValue() ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java index 60d08c99a383..ae6c1ce24910 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/DomainModelCategorizationCollector.java @@ -87,6 +87,9 @@ public void apply(JaxbEntityMappingsImpl jaxbRoot, XmlDocumentContext xmlDocumen getGlobalRegistrations().collectQueryReferences( jaxbRoot, xmlDocumentContext ); getGlobalRegistrations().collectDataBaseObject( jaxbRoot.getDatabaseObjects() ); + + getGlobalRegistrations().collectHqlImports( jaxbRoot.getHqlImports(), jaxbRoot.getPackage() ); + // todo (7.0) : named graphs? } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java index 2c58f290d6ad..20acac633e6b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/internal/GlobalRegistrationsImpl.java @@ -30,6 +30,7 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbFetchProfileImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbFilterDefImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbGenericIdGeneratorImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbHqlImportImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbJavaTypeRegistrationImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbJdbcTypeRegistrationImpl; import org.hibernate.boot.jaxb.mapping.spi.JaxbNamedNativeStatementImpl; @@ -126,6 +127,7 @@ import static org.hibernate.boot.models.xml.internal.QueryProcessing.collectResultClasses; import static org.hibernate.boot.BootLogging.BOOT_LOGGER; import static org.hibernate.internal.util.StringHelper.isNotEmpty; +import static org.hibernate.internal.util.StringHelper.qualifyConditionallyIfNot; import static org.hibernate.internal.util.StringHelper.unqualify; import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty; @@ -692,6 +694,16 @@ public void collectImportRename(ClassDetails classDetails) { } } + public void collectHqlImports(List hqlImports, String packageName) { + for ( var hqlImport : hqlImports ) { + final String className = qualifyConditionallyIfNot( packageName, hqlImport.getClazz() ); + final String rename = hqlImport.getRename() != null + ? hqlImport.getRename() + : unqualify( className ); + collectImportRename( rename, className ); + } + } + public void collectImportRename(String rename, String name) { if ( importedRenameMap == null ) { importedRenameMap = new HashMap<>();