From ebbb36cf712413f9ff0aa21f8fa21cccfb5e509a Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 30 Apr 2024 15:51:01 -0500 Subject: [PATCH] HHH-18042 - ConstructorResults defined in XML are not applied --- .../internal/GlobalRegistrationsImpl.java | 4 + .../NamedResultSetMappingMementoImpl.java | 5 ++ .../ResultMementoInstantiationStandard.java | 9 +++ .../query/resultmapping/XmlOverrideTests.java | 81 +++++++++++++++++++ .../simple-resultset-mapping-override.xml | 19 +++++ 5 files changed, 118 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/XmlOverrideTests.java create mode 100644 hibernate-core/src/test/resources/mappings/query/simple-resultset-mapping-override.xml diff --git a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java index eab6f00f42..31e0b5c281 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/GlobalRegistrationsImpl.java @@ -914,6 +914,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { } } } + annotationListConsumer.accept( entityResults ); } @@ -941,6 +942,8 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { ); } } + + annotationListConsumer.accept( results ); } private void applyColumnResults( @@ -958,6 +961,7 @@ public class GlobalRegistrationsImpl implements GlobalRegistrations { columnResultAnnotation.setAttributeValue( "name", jaxbColumn.getName() ); applyAttributeIfSpecified( "type", sourceModelContext.getClassDetailsRegistry().resolveClassDetails( jaxbColumn.getClazz() ), columnResultAnnotation ); } + annotationListConsumer.accept( columnResults ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedResultSetMappingMementoImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedResultSetMappingMementoImpl.java index e7e479e93d..738ca88901 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/NamedResultSetMappingMementoImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/NamedResultSetMappingMementoImpl.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.internal; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -34,6 +35,10 @@ public class NamedResultSetMappingMementoImpl implements NamedResultSetMappingMe return name; } + public List getResultMementos() { + return Collections.unmodifiableList( resultMementos ); + } + @Override public void resolve( ResultSetMapping resultSetMapping, diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoInstantiationStandard.java b/hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoInstantiationStandard.java index c2419ac2c6..8c3f1d557b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoInstantiationStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/ResultMementoInstantiationStandard.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.internal; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -30,6 +31,14 @@ public class ResultMementoInstantiationStandard implements ResultMementoInstanti this.argumentMementos = argumentMementos; } + public JavaType getInstantiatedJavaType() { + return instantiatedJtd; + } + + public List getArgumentMementos() { + return Collections.unmodifiableList( argumentMementos ); + } + @Override public ResultBuilder resolve( Consumer querySpaceConsumer, diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/XmlOverrideTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/XmlOverrideTests.java new file mode 100644 index 0000000000..708a8ec9de --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/resultmapping/XmlOverrideTests.java @@ -0,0 +1,81 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.orm.test.query.resultmapping; + +import java.util.List; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.internal.NamedResultSetMappingMementoImpl; +import org.hibernate.query.internal.ResultMementoInstantiationStandard; +import org.hibernate.query.named.NamedObjectRepository; +import org.hibernate.query.named.NamedResultSetMappingMemento; +import org.hibernate.query.named.ResultMemento; + +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.ColumnResult; +import jakarta.persistence.ConstructorResult; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.SqlResultSetMapping; +import jakarta.persistence.SqlResultSetMappings; +import jakarta.persistence.Table; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Steve Ebersole + */ +@SuppressWarnings("JUnitMalformedDeclaration") +public class XmlOverrideTests { + @Test + @DomainModel( + annotatedClasses = SimpleEntity.class, + xmlMappings = "mappings/query/simple-resultset-mapping-override.xml" + ) + @SessionFactory + void testResultSetMappingOverride(SessionFactoryScope scope) { + final SessionFactoryImplementor sessionFactory = scope.getSessionFactory(); + final NamedObjectRepository namedObjectRepository = sessionFactory.getQueryEngine().getNamedObjectRepository(); + final NamedResultSetMappingMemento dtoMappingMemento = namedObjectRepository.getResultSetMappingMemento( "dto-mapping" ); + final NamedResultSetMappingMementoImpl mementoImpl = (NamedResultSetMappingMementoImpl) dtoMappingMemento; + final List resultMementos = mementoImpl.getResultMementos(); + assertThat( resultMementos ).hasSize( 1 ); + + final ResultMemento resultMemento = resultMementos.get( 0 ); + assertThat( resultMemento ).isInstanceOf( ResultMementoInstantiationStandard.class ); + final ResultMementoInstantiationStandard ctorMemento = (ResultMementoInstantiationStandard) resultMemento; + final Class resultClass = ctorMemento.getInstantiatedJavaType().getJavaTypeClass(); + assertThat( resultClass ).isEqualTo( Dto2.class ); + } + + @Entity(name="SimpleEntity") + @Table(name="SimpleEntity") + @SqlResultSetMappings({ + @SqlResultSetMapping( name = "dto-mapping", classes = { + @ConstructorResult( targetClass = Dto1.class, columns = { + @ColumnResult( name = "id", type = Integer.class ), + @ColumnResult( name = "name", type = String.class ) + }) + }), + @SqlResultSetMapping( name = "irrelevant", columns = @ColumnResult( name = "name", type = String.class ) ) + }) + public static class SimpleEntity { + @Id + private Integer id; + private String name; + } + + public record Dto1(Integer id, String name) { + } + + public record Dto2(Integer id, String name) { + } +} diff --git a/hibernate-core/src/test/resources/mappings/query/simple-resultset-mapping-override.xml b/hibernate-core/src/test/resources/mappings/query/simple-resultset-mapping-override.xml new file mode 100644 index 0000000000..a0f0636f49 --- /dev/null +++ b/hibernate-core/src/test/resources/mappings/query/simple-resultset-mapping-override.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + \ No newline at end of file