parent
671250afa6
commit
5f7c139f7e
|
@ -15,6 +15,9 @@ Document in release-notes:
|
||||||
* `NativeQuery#addScalar(Class)`
|
* `NativeQuery#addScalar(Class)`
|
||||||
* `NativeQuery#addScalar(Class,AttributeConverter)`
|
* `NativeQuery#addScalar(Class,AttributeConverter)`
|
||||||
* `NativeQuery#addScalar(Class,Class<AttributeConverter>)`
|
* `NativeQuery#addScalar(Class,Class<AttributeConverter>)`
|
||||||
|
* `NativeQuery#addAttributeResult(String,Class,String)`
|
||||||
|
* `NativeQuery#addAttributeResult(String,String,String)`
|
||||||
|
* `NativeQuery#addAttributeResult(String,Attribute)`
|
||||||
|
|
||||||
|
|
||||||
== Changes
|
== Changes
|
||||||
|
|
|
@ -536,7 +536,12 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getImportedName(String name) {
|
public String getImportedName(String name) {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
// we have to go back through TypeConfiguration / SessionFactory to get to the JpaMetamodel :(
|
||||||
|
final String qualifiedName = typeConfiguration.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getJpaMetamodel()
|
||||||
|
.qualifyImportableName( name );
|
||||||
|
return qualifiedName == null ? name : qualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@ import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.LockModeType;
|
import javax.persistence.LockModeType;
|
||||||
import javax.persistence.Parameter;
|
import javax.persistence.Parameter;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.metamodel.SingularAttribute;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
@ -131,6 +132,41 @@ public interface NativeQuery<T> extends Query<T>, SynchronizeableQuery {
|
||||||
*/
|
*/
|
||||||
<C> NativeQuery<T> addScalar(String columnAlias, Class<C> relationalJavaType, Class<? extends AttributeConverter<?,C>> converter);
|
<C> NativeQuery<T> addScalar(String columnAlias, Class<C> relationalJavaType, Class<? extends AttributeConverter<?,C>> converter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a result based on a specified attribute. Differs from adding a scalar in that
|
||||||
|
* any conversions or other semantics defined on the attribute are automatically applied
|
||||||
|
* to the mapping
|
||||||
|
*
|
||||||
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @since 6.0
|
||||||
|
*/
|
||||||
|
NativeQuery<T> addAttributeResult(String columnAlias, Class<?> entityJavaType, String attributePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a result based on a specified attribute. Differs from adding a scalar in that
|
||||||
|
* any conversions or other semantics defined on the attribute are automatically applied
|
||||||
|
* to the mapping
|
||||||
|
*
|
||||||
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @since 6.0
|
||||||
|
*/
|
||||||
|
NativeQuery<T> addAttributeResult(String columnAlias, String entityName, String attributePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a result based on a specified attribute. Differs from adding a scalar in that
|
||||||
|
* any conversions or other semantics defined on the attribute are automatically applied
|
||||||
|
* to the mapping.
|
||||||
|
*
|
||||||
|
* This form accepts the JPA Attribute mapping describing the attribute
|
||||||
|
*
|
||||||
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @since 6.0
|
||||||
|
*/
|
||||||
|
NativeQuery<T> addAttributeResult(String columnAlias, SingularAttribute<?,?> attribute);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new root return mapping, returning a {@link RootReturn} to allow
|
* Add a new root return mapping, returning a {@link RootReturn} to allow
|
||||||
* further definition.
|
* further definition.
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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.query.results;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
import org.hibernate.sql.results.graph.Fetch;
|
||||||
|
import org.hibernate.sql.results.graph.FetchParent;
|
||||||
|
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||||
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class AttributeResultBuilder implements ResultBuilder {
|
||||||
|
private final BasicValuedSingularAttributeMapping attributeMapping;
|
||||||
|
private final String columnAlias;
|
||||||
|
private final String entityName;
|
||||||
|
private final String attributePath;
|
||||||
|
|
||||||
|
public AttributeResultBuilder(
|
||||||
|
SingularAttributeMapping attributeMapping,
|
||||||
|
String columnAlias,
|
||||||
|
String entityName,
|
||||||
|
String attributePath) {
|
||||||
|
final boolean allowable = attributeMapping instanceof BasicValuedSingularAttributeMapping;
|
||||||
|
if ( !allowable ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Specified attribute [%s.%s] must be basic: %s",
|
||||||
|
entityName,
|
||||||
|
attributePath,
|
||||||
|
attributeMapping
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attributeMapping = (BasicValuedSingularAttributeMapping) attributeMapping;
|
||||||
|
this.columnAlias = columnAlias;
|
||||||
|
this.entityName = entityName;
|
||||||
|
this.attributePath = attributePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResult<?> buildReturn(
|
||||||
|
JdbcValuesMetadata jdbcResultsMetadata,
|
||||||
|
BiFunction<String, String, LegacyFetchBuilder> legacyFetchResolver,
|
||||||
|
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
final int resultSetPosition = jdbcResultsMetadata.resolveColumnPosition( columnAlias );
|
||||||
|
final int valuesArrayPosition = resultSetPosition - 1;
|
||||||
|
|
||||||
|
final SqlSelectionImpl sqlSelection = new SqlSelectionImpl( valuesArrayPosition, attributeMapping );
|
||||||
|
sqlSelectionConsumer.accept( sqlSelection );
|
||||||
|
|
||||||
|
return new BasicResult<>(
|
||||||
|
valuesArrayPosition,
|
||||||
|
columnAlias,
|
||||||
|
attributeMapping.getJavaTypeDescriptor(),
|
||||||
|
attributeMapping.getValueConverter()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,10 +6,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.query.results;
|
package org.hibernate.query.results;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.metamodel.EntityType;
|
||||||
|
import javax.persistence.metamodel.SingularAttribute;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
import org.hibernate.NotYetImplementedFor6Exception;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.RuntimeMetamodels;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
|
||||||
|
@ -64,10 +72,92 @@ public class Builders {
|
||||||
throw new NotYetImplementedFor6Exception();
|
throw new NotYetImplementedFor6Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ResultBuilder attributeResult(
|
||||||
|
String columnAlias,
|
||||||
|
String entityName,
|
||||||
|
String attributePath,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
if ( attributePath.contains( "." ) ) {
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for defining a NativeQuery attribute result based on a composite path is not yet implemented"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final RuntimeMetamodels runtimeMetamodels = sessionFactory.getRuntimeMetamodels();
|
||||||
|
final String fullEntityName = runtimeMetamodels.getMappingMetamodel().getImportedName( entityName );
|
||||||
|
final EntityPersister entityMapping = runtimeMetamodels.getMappingMetamodel().findEntityDescriptor( fullEntityName );
|
||||||
|
if ( entityMapping == null ) {
|
||||||
|
throw new IllegalArgumentException( "Could not locate entity mapping : " + fullEntityName );
|
||||||
|
}
|
||||||
|
|
||||||
|
final AttributeMapping attributeMapping = entityMapping.findAttributeMapping( attributePath );
|
||||||
|
if ( attributeMapping == null ) {
|
||||||
|
throw new IllegalArgumentException( "Could not locate attribute mapping : " + fullEntityName + "." + attributePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( attributeMapping instanceof SingularAttributeMapping ) {
|
||||||
|
final SingularAttributeMapping singularAttributeMapping = (SingularAttributeMapping) attributeMapping;
|
||||||
|
return new AttributeResultBuilder( singularAttributeMapping, columnAlias, fullEntityName, attributePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"Specified attribute mapping [%s.%s] not a basic attribute: %s",
|
||||||
|
fullEntityName,
|
||||||
|
attributePath,
|
||||||
|
attributeMapping
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultBuilder attributeResult(String columnAlias, SingularAttribute<?, ?> attribute) {
|
||||||
|
if ( ! ( attribute.getDeclaringType() instanceof EntityType ) ) {
|
||||||
|
throw new NotYetImplementedFor6Exception(
|
||||||
|
"Support for defining a NativeQuery attribute result based on a composite path is not yet implemented"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotYetImplementedFor6Exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a EntityResultBuilder allowing for further configuring of the mapping.
|
||||||
|
*
|
||||||
|
* @param tableAlias
|
||||||
|
* @param entityName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public static EntityResultBuilder entity(String tableAlias, String entityName) {
|
public static EntityResultBuilder entity(String tableAlias, String entityName) {
|
||||||
throw new NotYetImplementedFor6Exception( );
|
throw new NotYetImplementedFor6Exception( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a EntityResultBuilder that does not allow any further configuring of the mapping.
|
||||||
|
*
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(Class)
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(String)
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(String, Class)
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(String, String)
|
||||||
|
*/
|
||||||
|
public static CalculatedEntityResultBuilder entityCalculated(String tableAlias, String entityName) {
|
||||||
|
return entityCalculated( tableAlias, entityName, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a EntityResultBuilder that does not allow any further configuring of the mapping.
|
||||||
|
*
|
||||||
|
* @see #entityCalculated(String, String)
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(String, Class, LockMode)
|
||||||
|
* @see org.hibernate.query.NativeQuery#addEntity(String, String, LockMode)
|
||||||
|
*/
|
||||||
|
public static CalculatedEntityResultBuilder entityCalculated(
|
||||||
|
String tableAlias,
|
||||||
|
String entityName,
|
||||||
|
LockMode explicitLockMode) {
|
||||||
|
return new CalculatedEntityResultBuilder( tableAlias, entityName, explicitLockMode );
|
||||||
|
}
|
||||||
|
|
||||||
public static LegacyFetchBuilder fetch(String tableAlias, String ownerTableAlias, String joinPropertyName) {
|
public static LegacyFetchBuilder fetch(String tableAlias, String ownerTableAlias, String joinPropertyName) {
|
||||||
throw new NotYetImplementedFor6Exception( );
|
throw new NotYetImplementedFor6Exception( );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.query.results;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.LockMode;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
|
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity DomainResult builder for cases when Hibernate implicitly
|
||||||
|
* calculates the mapping
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CalculatedEntityResultBuilder implements ResultBuilder {
|
||||||
|
private final String tableAlias;
|
||||||
|
private final String entityName;
|
||||||
|
private final LockMode explicitLockMode;
|
||||||
|
|
||||||
|
public CalculatedEntityResultBuilder(
|
||||||
|
String tableAlias,
|
||||||
|
String entityName,
|
||||||
|
LockMode explicitLockMode) {
|
||||||
|
this.tableAlias = tableAlias;
|
||||||
|
this.entityName = entityName;
|
||||||
|
this.explicitLockMode = explicitLockMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DomainResult<?> buildReturn(
|
||||||
|
JdbcValuesMetadata jdbcResultsMetadata,
|
||||||
|
BiFunction<String, String, LegacyFetchBuilder> legacyFetchResolver,
|
||||||
|
Consumer<SqlSelection> sqlSelectionConsumer,
|
||||||
|
SessionFactoryImplementor sessionFactory) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import javax.persistence.LockModeType;
|
||||||
import javax.persistence.Parameter;
|
import javax.persistence.Parameter;
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.metamodel.SingularAttribute;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
@ -511,6 +512,30 @@ public class NativeQueryImpl<R>
|
||||||
return registerBuilder( Builders.scalar( columnAlias, relationalJavaType, converter, getSessionFactory() ) );
|
return registerBuilder( Builders.scalar( columnAlias, relationalJavaType, converter, getSessionFactory() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeQueryImplementor<R> addAttributeResult(
|
||||||
|
String columnAlias,
|
||||||
|
Class<?> entityJavaType,
|
||||||
|
String attributePath) {
|
||||||
|
return addAttributeResult( columnAlias, entityJavaType.getName(), attributePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeQueryImplementor<R> addAttributeResult(
|
||||||
|
String columnAlias,
|
||||||
|
String entityName,
|
||||||
|
String attributePath) {
|
||||||
|
registerBuilder( Builders.attributeResult( columnAlias, entityName, attributePath, getSessionFactory() ) );
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NativeQueryImplementor<R> addAttributeResult(
|
||||||
|
String columnAlias,
|
||||||
|
SingularAttribute<?, ?> attribute) {
|
||||||
|
registerBuilder( Builders.attributeResult( columnAlias, attribute ) );
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityResultBuilder addRoot(String tableAlias, String entityName) {
|
public EntityResultBuilder addRoot(String tableAlias, String entityName) {
|
||||||
|
@ -534,13 +559,13 @@ public class NativeQueryImpl<R>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NativeQueryImplementor<R> addEntity(String tableAlias, String entityName) {
|
public NativeQueryImplementor<R> addEntity(String tableAlias, String entityName) {
|
||||||
addRoot( tableAlias, entityName );
|
registerBuilder( Builders.entityCalculated( tableAlias, entityName ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NativeQueryImplementor<R> addEntity(String tableAlias, String entityName, LockMode lockMode) {
|
public NativeQueryImplementor<R> addEntity(String tableAlias, String entityName, LockMode lockMode) {
|
||||||
addRoot( tableAlias, entityName ).setLockMode( lockMode );
|
registerBuilder( Builders.entityCalculated( tableAlias, entityName, lockMode ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import javax.persistence.FlushModeType;
|
||||||
import javax.persistence.LockModeType;
|
import javax.persistence.LockModeType;
|
||||||
import javax.persistence.Parameter;
|
import javax.persistence.Parameter;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
import javax.persistence.metamodel.SingularAttribute;
|
||||||
|
|
||||||
import org.hibernate.CacheMode;
|
import org.hibernate.CacheMode;
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
|
@ -65,6 +66,15 @@ public interface NativeQueryImplementor<R> extends QueryImplementor<R>, NativeQu
|
||||||
@Override
|
@Override
|
||||||
<C> NativeQueryImplementor<R> addScalar(String columnAlias, Class<C> relationalJavaType, Class<? extends AttributeConverter<?,C>> converter);
|
<C> NativeQueryImplementor<R> addScalar(String columnAlias, Class<C> relationalJavaType, Class<? extends AttributeConverter<?,C>> converter);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
NativeQueryImplementor<R> addAttributeResult(String columnAlias, Class<?> entityJavaType, String attributePath);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
NativeQueryImplementor<R> addAttributeResult(String columnAlias, String entityName, String attributePath);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
NativeQueryImplementor<R> addAttributeResult(String columnAlias, SingularAttribute<?, ?> attribute);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
EntityResultBuilder addRoot(String tableAlias, String entityName);
|
EntityResultBuilder addRoot(String tableAlias, String entityName);
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ public class EntityGraphNativeQueryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected( reason = "Uses an implicit entity/root return, which is not yet implemented" )
|
|
||||||
void testNativeQueryLoadGraph(SessionFactoryScope scope) {
|
void testNativeQueryLoadGraph(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
|
@ -115,7 +114,6 @@ public class EntityGraphNativeQueryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@FailureExpected( reason = "Uses an implicit entity/root return, which is not yet implemented" )
|
|
||||||
void testNativeQueryFetchGraph(SessionFactoryScope scope) {
|
void testNativeQueryFetchGraph(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
|
|
|
@ -17,13 +17,11 @@ import org.hibernate.metamodel.mapping.ModelPart;
|
||||||
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
|
||||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests;
|
|
||||||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
@ -47,7 +45,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
standardModels = StandardDomainModel.GAMBIT
|
standardModels = StandardDomainModel.GAMBIT
|
||||||
)
|
)
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
public class NativeQueryScalarTests {
|
public class NativeQueryResultBuilderTests {
|
||||||
public static final String STRING_VALUE = "a string value";
|
public static final String STRING_VALUE = "a string value";
|
||||||
public static final String URL_STRING = "http://hibernate.org";
|
public static final String URL_STRING = "http://hibernate.org";
|
||||||
|
|
||||||
|
@ -220,6 +218,31 @@ public class NativeQueryScalarTests {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConvertedAttributeBasedBuilder(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final NativeQueryImplementor qry = session.createNativeQuery(
|
||||||
|
"select converted_gender from EntityOfBasics"
|
||||||
|
);
|
||||||
|
|
||||||
|
qry.addAttributeResult(
|
||||||
|
"converted_gender",
|
||||||
|
"EntityOfBasics",
|
||||||
|
"convertedGender"
|
||||||
|
);
|
||||||
|
|
||||||
|
final List results = qry.list();
|
||||||
|
assertThat( results.size(), is( 1 ) );
|
||||||
|
|
||||||
|
final Object result = results.get( 0 );
|
||||||
|
assertThat( result, instanceOf( EntityOfBasics.Gender.class ) );
|
||||||
|
|
||||||
|
assertThat( result, is( EntityOfBasics.Gender.OTHER ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public void verifyModel(SessionFactoryScope scope) {
|
public void verifyModel(SessionFactoryScope scope) {
|
||||||
final EntityMappingType entityDescriptor = scope.getSessionFactory()
|
final EntityMappingType entityDescriptor = scope.getSessionFactory()
|
Loading…
Reference in New Issue