HHH-18042 - ConstructorResults defined in XML are not applied

This commit is contained in:
Steve Ebersole 2024-04-30 15:51:01 -05:00
parent 356b729c29
commit ebbb36cf71
5 changed files with 118 additions and 0 deletions

View File

@ -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 );
}

View File

@ -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<ResultMemento> getResultMementos() {
return Collections.unmodifiableList( resultMementos );
}
@Override
public void resolve(
ResultSetMapping resultSetMapping,

View File

@ -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<ArgumentMemento> getArgumentMementos() {
return Collections.unmodifiableList( argumentMementos );
}
@Override
public ResultBuilder resolve(
Consumer<String> querySpaceConsumer,

View File

@ -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<ResultMemento> 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) {
}
}

View File

@ -0,0 +1,19 @@
<!--
~ 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.
-->
<entity-mappings xmlns="https://jakarta.ee/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm/orm_3_2.xsd"
version="3.2">
<sql-result-set-mapping name="dto-mapping">
<constructor-result target-class="org.hibernate.orm.test.query.resultmapping.XmlOverrideTests$Dto2">
<column name="id" class="java.lang.Integer"/>
<column name="name" class="java.lang.String"/>
</constructor-result>
</sql-result-set-mapping>
</entity-mappings>