diff --git a/hibernate-core/src/main/java/org/hibernate/boot/BootLogging.java b/hibernate-core/src/main/java/org/hibernate/boot/BootLogging.java new file mode 100644 index 0000000000..67f079487d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/BootLogging.java @@ -0,0 +1,21 @@ +/* + * 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.boot; + +import org.jboss.logging.Logger; + +/** + * @author Steve Ebersole + */ +public class BootLogging { + public static final String NAME = "org.hibernate.orm.boot"; + + public static final Logger LOGGER = Logger.getLogger( NAME ); + + public static final boolean DEBUG_ENABLED = LOGGER.isDebugEnabled(); + public static final boolean TRACE_ENABLED = LOGGER.isTraceEnabled(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java b/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java index 4c1358a9b1..b529e32577 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/Metadata.java @@ -14,10 +14,10 @@ import org.hibernate.SessionFactory; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; import org.hibernate.boot.model.relational.Database; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; -import org.hibernate.boot.spi.NamedProcedureCallDefinition; -import org.hibernate.boot.spi.NamedResultSetMappingDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.Mapping; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 804deedc4f..16d3e521f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -58,10 +58,10 @@ import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingOptions; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; -import org.hibernate.boot.spi.NamedProcedureCallDefinition; -import org.hibernate.boot.spi.NamedResultSetMappingDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.boot.spi.NaturalIdUniqueKeyBinder; import org.hibernate.cfg.AnnotatedClassType; import org.hibernate.cfg.AvailableSettings; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java index 5157e470b6..fac7ec0eda 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java @@ -24,17 +24,16 @@ import org.hibernate.SessionFactory; import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; -import org.hibernate.boot.model.TypeDefinitionRegistry; import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.MetadataBuildingOptions; import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; -import org.hibernate.boot.spi.NamedProcedureCallDefinition; -import org.hibernate.boot.spi.NamedResultSetMappingDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.boot.spi.SessionFactoryBuilderFactory; import org.hibernate.boot.spi.SessionFactoryBuilderImplementor; import org.hibernate.boot.spi.SessionFactoryBuilderService; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedHqlQueryDefinitionImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedHqlQueryDefinitionImpl.java index e2a8983697..c36fbecb0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedHqlQueryDefinitionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedHqlQueryDefinitionImpl.java @@ -12,7 +12,7 @@ import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.LockOptions; import org.hibernate.boot.spi.AbstractNamedQueryDefinition; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.hql.spi.NamedHqlQueryMemento; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedNativeQueryDefinitionImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedNativeQueryDefinitionImpl.java index 1f1642cde7..d0852042c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedNativeQueryDefinitionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedNativeQueryDefinitionImpl.java @@ -13,7 +13,7 @@ import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.spi.AbstractNamedQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedProcedureCallDefinitionImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedProcedureCallDefinitionImpl.java index 27c9807e34..53d9f9d48c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedProcedureCallDefinitionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/NamedProcedureCallDefinitionImpl.java @@ -17,7 +17,7 @@ import javax.persistence.StoredProcedureParameter; import org.hibernate.MappingException; import org.hibernate.NotYetImplementedFor6Exception; -import org.hibernate.boot.spi.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.annotations.QueryHintDefinition; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/MappingDocument.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/MappingDocument.java index fd25665ee6..6f3132bce5 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/MappingDocument.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/MappingDocument.java @@ -28,7 +28,7 @@ import org.hibernate.boot.model.source.spi.MetadataSourceProcessor; import org.hibernate.boot.model.source.spi.ToolingHintContext; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.ClassLoaderAccess; -import org.hibernate.boot.spi.HbmResultSetMappingDefinition; +import org.hibernate.boot.query.HbmResultSetMappingDefinition; import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MappingDefaults; import org.hibernate.boot.spi.MetadataBuildingContext; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java index ffa42bdc2f..c2c4167435 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/NamedQueryBinder.java @@ -17,9 +17,10 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmQueryParamType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmSynchronizeType; -import org.hibernate.boot.spi.HbmResultSetMappingDefinition; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.boot.query.HbmResultSetMappingDefinition; +import org.hibernate.boot.query.HbmResultSetMappingDefinitionBuilder; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinitionBuilder; import org.hibernate.internal.log.DeprecationLogger; import org.hibernate.internal.util.StringHelper; @@ -103,7 +104,7 @@ public class NamedQueryBinder { final String registrationName = prefix + namedQueryBinding.getName(); - final NamedNativeQueryDefinition.Builder builder = new NamedNativeQueryDefinition.Builder( registrationName ) + final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( registrationName ) .setComment( namedQueryBinding.getComment() ) .setCacheable( namedQueryBinding.isCacheable() ) .setCacheMode( namedQueryBinding.getCacheMode() ) @@ -114,7 +115,7 @@ public class NamedQueryBinder { .setFetchSize( namedQueryBinding.getFetchSize() ) .setResultSetMappingName( namedQueryBinding.getResultsetRef() ); - final HbmResultSetMappingDefinition.Builder implicitResultSetMappingBuilder = new HbmResultSetMappingDefinition.Builder( registrationName ); + final HbmResultSetMappingDefinitionBuilder implicitResultSetMappingBuilder = new HbmResultSetMappingDefinitionBuilder( registrationName ); boolean foundQuery = false; @@ -160,8 +161,8 @@ public class NamedQueryBinder { private static boolean processNamedQueryContentItem( Object content, - NamedNativeQueryDefinition.Builder queryBuilder, - HbmResultSetMappingDefinition.Builder implicitResultSetMappingBuilder, + NamedNativeQueryDefinitionBuilder queryBuilder, + HbmResultSetMappingDefinitionBuilder implicitResultSetMappingBuilder, JaxbHbmNamedNativeQueryType namedQueryBinding, HbmLocalMetadataBuildingContext context) { if ( content instanceof String ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ResultSetMappingBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ResultSetMappingBinder.java index 72b840acbd..dbfa96706c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ResultSetMappingBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ResultSetMappingBinder.java @@ -24,7 +24,8 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType; import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType; import org.hibernate.boot.jaxb.hbm.spi.NativeQueryNonScalarRootReturn; import org.hibernate.boot.jaxb.hbm.spi.ResultSetMappingBindingDefinition; -import org.hibernate.boot.spi.HbmResultSetMappingDefinition; +import org.hibernate.boot.query.HbmResultSetMappingDefinition; +import org.hibernate.boot.query.HbmResultSetMappingDefinitionBuilder; import org.hibernate.engine.query.spi.sql.NativeSQLQueryCollectionReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryJoinReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; @@ -62,7 +63,7 @@ public abstract class ResultSetMappingBinder { throw new MappingException( "ResultSet mapping did not specify name", context.getOrigin() ); } - final HbmResultSetMappingDefinition.Builder builder = new HbmResultSetMappingDefinition.Builder( resultSetMappingSource.getName() ); + final HbmResultSetMappingDefinitionBuilder builder = new HbmResultSetMappingDefinitionBuilder( resultSetMappingSource.getName() ); for ( Object valueMappingSource : resultSetMappingSource.getValueMappingSources() ) { if ( valueMappingSource instanceof JaxbHbmNativeQueryReturnType ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/AbstractNamedQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/query/AbstractNamedQueryBuilder.java new file mode 100644 index 0000000000..7c77b26675 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/AbstractNamedQueryBuilder.java @@ -0,0 +1,148 @@ +/* + * 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.boot.query; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.CacheMode; +import org.hibernate.FlushMode; +import org.hibernate.LockOptions; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractNamedQueryBuilder> { + private final String name; + + private Boolean cacheable; + private String cacheRegion; + private CacheMode cacheMode; + + private FlushMode flushMode; + private Boolean readOnly; + + private LockOptions lockOptions; + + private Integer timeout; + private Integer fetchSize; + + private String comment; + + private Map hints; + + public AbstractNamedQueryBuilder(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + protected abstract T getThis(); + + public T setCacheable(Boolean cacheable) { + this.cacheable = cacheable; + return getThis(); + } + + public T setCacheRegion(String cacheRegion) { + this.cacheRegion = cacheRegion; + return getThis(); + } + + public T setCacheMode(CacheMode cacheMode) { + this.cacheMode = cacheMode; + return getThis(); + } + + public T setLockOptions(LockOptions lockOptions) { + this.lockOptions = lockOptions; + return getThis(); + } + + public T setTimeout(Integer timeout) { + this.timeout = timeout; + return getThis(); + } + + public T setFlushMode(FlushMode flushMode) { + this.flushMode = flushMode; + return getThis(); + } + + public T setReadOnly(Boolean readOnly) { + this.readOnly = readOnly; + return getThis(); + } + + public T setFetchSize(Integer fetchSize) { + this.fetchSize = fetchSize; + return getThis(); + } + + public T setComment(String comment) { + this.comment = comment; + return getThis(); + } + + public Boolean getCacheable() { + return cacheable; + } + + public String getCacheRegion() { + return cacheRegion; + } + + public CacheMode getCacheMode() { + return cacheMode; + } + + public FlushMode getFlushMode() { + return flushMode; + } + + public Boolean getReadOnly() { + return readOnly; + } + + public LockOptions getLockOptions() { + return lockOptions; + } + + public Integer getTimeout() { + return timeout; + } + + public Integer getFetchSize() { + return fetchSize; + } + + public String getComment() { + return comment; + } + + public void addHint(String name, Object value) { + if ( hints == null ) { + hints = new HashMap<>(); + } + hints.put( name, value ); + } + + public T addHints(Map hintsMap) { + if ( hints == null ) { + hints = new HashMap<>(); + } + hints.putAll( hintsMap ); + + return getThis(); + } + + public Map getHints() { + return hints; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinition.java new file mode 100644 index 0000000000..60e5cc8753 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinition.java @@ -0,0 +1,179 @@ +/* + * 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.boot.query; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.named.NamedResultSetMappingMemento; +import org.hibernate.query.results.Builders; +import org.hibernate.query.results.ScalarResultBuilder; +import org.hibernate.type.BasicType; + +/** + * Boot-time descriptor of a result-set-mapping as defined in an `hbm.xml` file + * either implicitly or explicitly + * + * @see org.hibernate.Session#createNativeQuery(String, String) + * @see org.hibernate.Session#createStoredProcedureCall(String, String[]) + * @see org.hibernate.Session#createStoredProcedureCall(String, String[]) + * + * @author Steve Ebersole + */ +public class HbmResultSetMappingDefinition implements NamedResultSetMappingDefinition { + // todo (6.0) : see note on org.hibernate.boot.query.SqlResultSetMappingDefinition + + private final String registrationName; + + private final ResultMapping rootEntityReturn; + private final ResultMapping rootCollectionReturn; + private final List joinReturns; + private final List scalarResultMappings; + + public HbmResultSetMappingDefinition( + String registrationName, + ResultMapping rootEntityReturn, + ResultMapping rootCollectionReturn, + List joinReturns, + List scalarResultMappings) { + this.registrationName = registrationName; + + this.rootEntityReturn = rootEntityReturn; + this.rootCollectionReturn = rootCollectionReturn; + this.joinReturns = joinReturns; + this.scalarResultMappings = scalarResultMappings; + } + + @Override + public String getRegistrationName() { + return registrationName; + } + + @Override + public NamedResultSetMappingMemento resolve(SessionFactoryImplementor factory) { + final List scalarResultBuilders; + if ( scalarResultMappings == null || scalarResultMappings.isEmpty() ) { + scalarResultBuilders = null; + } + else { + scalarResultBuilders = new ArrayList<>( scalarResultMappings.size() ); + scalarResultMappings.forEach( + resultMapping -> { + scalarResultBuilders.add( resultMapping.resolve( factory ) ); + } + ); + } + + throw new NotYetImplementedFor6Exception( getClass() ); + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // `hbm.xml` returns + + /** + * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType + */ + public interface RootEntityMappingDefinition extends ResultMapping { + String getEntityName(); + + String getSqlAlias(); + + List getProperties(); + + String getDiscriminatorColumnName(); + + LockMode getLockMode(); + } + + /** + * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryPropertyReturnType + */ + public interface HbmPropertyMappingDefinition extends ResultMapping { + String getPropertyPath(); + List getColumnNames(); + } + + /** + * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryJoinReturnType + */ + public interface JoinMappingDefinition extends ResultMapping { + String getJoinedPropertyPath(); + + String getSqlAlias(); + + List getProperties(); + + LockMode getLockMode(); + } + + /** + * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryCollectionLoadReturnType + */ + public interface RootCollectionMappingDefinition extends ResultMapping { + String getCollectionRole(); + + String getSqlAlias(); + + List getProperties(); + + LockMode getLockMode(); + } + + /** + * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType + */ + public static class ScalarMappingDefinition implements ResultMapping { + private final String columnName; + private final String hibernateTypeName; + + public ScalarMappingDefinition(String columnName, String hibernateTypeName) { + this.columnName = columnName; + this.hibernateTypeName = hibernateTypeName; + } + + public String getColumnName() { + return columnName; + } + + public String getHibernateTypeName() { + return hibernateTypeName; + } + + @Override + public ScalarResultBuilder resolve(SessionFactoryImplementor factory) { + if ( hibernateTypeName != null ) { + final BasicType namedType = factory.getTypeConfiguration() + .getBasicTypeRegistry() + .getRegisteredType( hibernateTypeName ); + + if ( namedType == null ) { + throw new IllegalArgumentException( "Could not resolve named type : " + hibernateTypeName ); + } + + return Builders.scalar( columnName ); + } + + // todo (6.0) : column name may be optional in HBM - double check + + return Builders.scalar( columnName ); + } + } + + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // JPA returns + + /** + * @see javax.persistence.ColumnResult + */ + interface JpaColumnResult { + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinitionBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinitionBuilder.java new file mode 100644 index 0000000000..94edc83582 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDefinitionBuilder.java @@ -0,0 +1,90 @@ +/* + * 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.boot.query; + +import java.util.List; + +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.boot.MappingException; +import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryCollectionLoadReturnType; +import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryJoinReturnType; +import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType; +import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType; +import org.hibernate.boot.model.source.internal.hbm.HbmLocalMetadataBuildingContext; + +/** + * @author Steve Ebersole + */ +public class HbmResultSetMappingDefinitionBuilder { + private final String registrationName; + + private NamedResultSetMappingDefinition.ResultMapping rootEntityReturn; + private NamedResultSetMappingDefinition.ResultMapping rootCollectionReturn; + private List joinReturns; + private List rootScalarReturns; + + public HbmResultSetMappingDefinitionBuilder(String queryRegistrationName) { + this.registrationName = queryRegistrationName; + } + + public String getRegistrationName() { + return registrationName; + } + + public HbmResultSetMappingDefinitionBuilder addReturn(JaxbHbmNativeQueryScalarReturnType returnMapping) { + rootScalarReturns.add( + new HbmResultSetMappingDefinition.ScalarMappingDefinition( + returnMapping.getColumn(), + returnMapping.getType() + ) + ); + return this; + } + + public HbmResultSetMappingDefinitionBuilder addReturn(JaxbHbmNativeQueryReturnType returnMapping) { + throw new NotYetImplementedFor6Exception(); + } + + public void addReturn(JaxbHbmNativeQueryJoinReturnType returnMapping) { + throw new NotYetImplementedFor6Exception(); + } + + public void addReturn(JaxbHbmNativeQueryCollectionLoadReturnType returnMapping) { + throw new NotYetImplementedFor6Exception(); + } + + public boolean hasAnyReturns() { + return rootEntityReturn != null || rootCollectionReturn != null || rootScalarReturns != null; + } + + public HbmResultSetMappingDefinition build(HbmLocalMetadataBuildingContext context) { + if ( rootCollectionReturn != null + && ( rootEntityReturn != null || rootScalarReturns != null ) ) { + throw new MappingException( + "HBM return-collection ResultSet mapping cannot define an entity or scalar returns : " + registrationName, + context.getOrigin() + ); + } + + if ( joinReturns != null ) { + if ( rootEntityReturn == null && rootCollectionReturn == null ) { + throw new MappingException( + "HBM return-join ResultSet mapping must be used in conjunction with root entity or collection return : " + registrationName, + context.getOrigin() + ); + } + } + + return new HbmResultSetMappingDefinition( + registrationName, + rootEntityReturn, + rootCollectionReturn, + joinReturns, + rootScalarReturns + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedCallableQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedCallableQueryDefinition.java similarity index 96% rename from hibernate-core/src/main/java/org/hibernate/boot/spi/NamedCallableQueryDefinition.java rename to hibernate-core/src/main/java/org/hibernate/boot/query/NamedCallableQueryDefinition.java index 00e7affb72..b56ff9b084 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedCallableQueryDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedCallableQueryDefinition.java @@ -4,7 +4,7 @@ * 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.boot.spi; +package org.hibernate.boot.query; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.procedure.internal.NamedCallableQueryMementoImpl; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedHqlQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedHqlQueryDefinition.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/boot/spi/NamedHqlQueryDefinition.java rename to hibernate-core/src/main/java/org/hibernate/boot/query/NamedHqlQueryDefinition.java index 10eed00bd9..2f6f205b7c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedHqlQueryDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedHqlQueryDefinition.java @@ -4,7 +4,7 @@ * 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.boot.spi; +package org.hibernate.boot.query; import java.util.HashMap; import java.util.Map; @@ -29,7 +29,7 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition { @Override NamedHqlQueryMemento resolve(SessionFactoryImplementor factory); - class Builder extends AbstractNamedQueryDefinition.AbstractBuilder { + class Builder extends AbstractNamedQueryBuilder { private String hqlString; private Integer firstResult; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinition.java new file mode 100644 index 0000000000..5f2c2cddca --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinition.java @@ -0,0 +1,38 @@ +/* + * 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.boot.query; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl; +import org.hibernate.boot.spi.AbstractNamedQueryDefinition; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.sql.spi.NamedNativeQueryMemento; + +/** + * Boot-time descriptor of a named native query, as defined in + * annotations or xml + * + * @see javax.persistence.NamedNativeQuery + * @see org.hibernate.annotations.NamedNativeQuery + * + * @author Steve Ebersole + * @author Gavin King + */ +public interface NamedNativeQueryDefinition extends NamedQueryDefinition { + String getSqlQueryString(); + + String getResultSetMappingName(); + String getResultSetMappingClassName(); + + @Override + NamedNativeQueryMemento resolve(SessionFactoryImplementor factory); + +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinitionBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinitionBuilder.java new file mode 100644 index 0000000000..b334aded2e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedNativeQueryDefinitionBuilder.java @@ -0,0 +1,158 @@ +/* + * 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.boot.query; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.hibernate.CacheMode; +import org.hibernate.FlushMode; +import org.hibernate.LockOptions; +import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl; + +/** + * @author Steve Ebersole + */ +public class NamedNativeQueryDefinitionBuilder extends AbstractNamedQueryBuilder { + private String sqlString; + + private String resultSetMappingName; + private String resultSetMappingClassName; + + private Set querySpaces; + + private Map parameterTypes; + + public NamedNativeQueryDefinitionBuilder(String name) { + super( name ); + } + + public NamedNativeQueryDefinitionBuilder setSqlString(String sqlString) { + this.sqlString = sqlString; + return getThis(); + } + + public NamedNativeQueryDefinition build() { + return new NamedNativeQueryDefinitionImpl( + getName(), + sqlString, + resultSetMappingName, + resultSetMappingClassName, + getQuerySpaces(), + getCacheable(), + getCacheRegion(), + getCacheMode(), + getFlushMode(), + getReadOnly(), + getTimeout(), + getFetchSize(), + getComment(), + getHints() + ); + } + + @Override + protected NamedNativeQueryDefinitionBuilder getThis() { + return this; + } + + public Set getQuerySpaces() { + return querySpaces; + } + + public NamedNativeQueryDefinitionBuilder addSynchronizedQuerySpaces(Set querySpaces) { + if ( querySpaces == null || querySpaces.isEmpty() ) { + return this; + } + + if ( this.querySpaces == null ) { + this.querySpaces = new HashSet<>(); + } + + this.querySpaces.addAll( querySpaces ); + + return getThis(); + } + + public NamedNativeQueryDefinitionBuilder addSynchronizedQuerySpace(String space) { + if ( this.querySpaces == null ) { + this.querySpaces = new HashSet<>(); + } + this.querySpaces.add( space ); + return getThis(); + } + + public NamedNativeQueryDefinitionBuilder setQuerySpaces(Set spaces) { + this.querySpaces = spaces; + return this; + } + + public NamedNativeQueryDefinitionBuilder setResultSetMappingName(String resultSetMappingName) { + this.resultSetMappingName = resultSetMappingName; + return this; + } + + public NamedNativeQueryDefinitionBuilder setResultSetMappingClassName(String resultSetMappingClassName) { + this.resultSetMappingClassName = resultSetMappingClassName; + return this; + } + + @Override + public NamedNativeQueryDefinitionBuilder setFetchSize(Integer fetchSize) { + return (NamedNativeQueryDefinitionBuilder) super.setFetchSize( fetchSize ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setCacheable(Boolean cacheable) { + return (NamedNativeQueryDefinitionBuilder) super.setCacheable( cacheable ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setCacheRegion(String cacheRegion) { + return (NamedNativeQueryDefinitionBuilder) super.setCacheRegion( cacheRegion ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setCacheMode(CacheMode cacheMode) { + return (NamedNativeQueryDefinitionBuilder) super.setCacheMode( cacheMode ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setLockOptions(LockOptions lockOptions) { + return (NamedNativeQueryDefinitionBuilder) super.setLockOptions( lockOptions ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setTimeout(Integer timeout) { + return (NamedNativeQueryDefinitionBuilder) super.setTimeout( timeout ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setFlushMode(FlushMode flushMode) { + return (NamedNativeQueryDefinitionBuilder) super.setFlushMode( flushMode ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setReadOnly(Boolean readOnly) { + return (NamedNativeQueryDefinitionBuilder) super.setReadOnly( readOnly ); + } + + @Override + public NamedNativeQueryDefinitionBuilder setComment(String comment) { + return (NamedNativeQueryDefinitionBuilder) super.setComment( comment ); + } + + public void addParameterTypeHint(String name, String type) { + if ( parameterTypes == null ) { + parameterTypes = new HashMap<>(); + } + + parameterTypes.put( name, type ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedProcedureCallDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedProcedureCallDefinition.java similarity index 95% rename from hibernate-core/src/main/java/org/hibernate/boot/spi/NamedProcedureCallDefinition.java rename to hibernate-core/src/main/java/org/hibernate/boot/query/NamedProcedureCallDefinition.java index f0cecbd2ae..595e3c13f6 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedProcedureCallDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedProcedureCallDefinition.java @@ -4,7 +4,7 @@ * 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.boot.spi; +package org.hibernate.boot.query; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.procedure.spi.NamedCallableQueryMemento; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedQueryDefinition.java similarity index 96% rename from hibernate-core/src/main/java/org/hibernate/boot/spi/NamedQueryDefinition.java rename to hibernate-core/src/main/java/org/hibernate/boot/query/NamedQueryDefinition.java index f398679c97..e42b8c7c12 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedQueryDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedQueryDefinition.java @@ -4,7 +4,7 @@ * 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.boot.spi; +package org.hibernate.boot.query; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.named.NamedQueryMemento; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedResultSetMappingDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedResultSetMappingDefinition.java similarity index 56% rename from hibernate-core/src/main/java/org/hibernate/boot/spi/NamedResultSetMappingDefinition.java rename to hibernate-core/src/main/java/org/hibernate/boot/query/NamedResultSetMappingDefinition.java index 9a237e099e..981551e4ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedResultSetMappingDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/NamedResultSetMappingDefinition.java @@ -4,12 +4,20 @@ * 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.boot.spi; +package org.hibernate.boot.query; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.named.NamedResultSetMappingMemento; +import org.hibernate.query.results.ResultBuilder; /** + * Models the "boot view" of a ResultSet mapping used in the mapping + * of native and procedure queries. + * + * Ultimately used to generate a NamedResultSetMappingMemento that is + * stored in the {@link org.hibernate.query.named.NamedQueryRepository} + * for availability at runtime + * * @author Steve Ebersole */ public interface NamedResultSetMappingDefinition { @@ -18,6 +26,13 @@ public interface NamedResultSetMappingDefinition { */ String getRegistrationName(); + /** + * Contract for the individual result mappings + */ + interface ResultMapping { + ResultBuilder resolve(SessionFactoryImplementor factory); + } + /** * Create the named runtime memento instance */ diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDefinition.java new file mode 100644 index 0000000000..7be378a400 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDefinition.java @@ -0,0 +1,154 @@ +/* + * 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.boot.query; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.ColumnResult; +import javax.persistence.SqlResultSetMapping; + +import org.hibernate.NotYetImplementedFor6Exception; +import org.hibernate.boot.BootLogging; +import org.hibernate.boot.spi.MetadataBuildingContext; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.query.internal.NamedResultSetMappingMementoImpl; +import org.hibernate.query.named.NamedResultSetMappingMemento; +import org.hibernate.query.results.ScalarResultBuilder; +import org.hibernate.query.results.StandardScalarResultBuilder; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + +/** + * @author Steve Ebersole + */ +public class SqlResultSetMappingDefinition implements NamedResultSetMappingDefinition { + + // todo (6.0) : we can probably reuse the NamedResultSetMappingDefinition + // implementation between HBM and annotation handling. We'd + // just need different "builders" for each source and handle the + // variances in those builders. But once we have a + // NamedResultSetMappingDefinition and all of its sub-parts, + // resolving to a memento is the same + // - + // additionally, consider having the sub-parts (the return + // representations) be what is used and handed to the + // NamedResultSetMappingMemento directly. They simply need + // to be capable of resolving themselves into ResultBuilders + // (`org.hibernate.query.results.ResultBuilder`) as part of the + // memento for its resolution + + public static SqlResultSetMappingDefinition from( + SqlResultSetMapping mappingAnnotation, + MetadataBuildingContext context) { + if ( mappingAnnotation.classes().length > 0 ) { + throw new NotYetImplementedFor6Exception( + "Support for dynamic-instantiation result mappings not yet implemented" + ); + } + + if ( mappingAnnotation.entities().length > 0 ) { + throw new NotYetImplementedFor6Exception( + "Support for entity result mappings not yet implemented" + ); + } + + if ( mappingAnnotation.columns().length == 0 ) { + throw new NotYetImplementedFor6Exception( "Should never get here" ); + } + + final List columnResultMappings; + if ( mappingAnnotation.columns().length == 0 ) { + columnResultMappings = null; + } + else { + columnResultMappings = new ArrayList<>( mappingAnnotation.columns().length ); + for ( int i = 0; i < mappingAnnotation.columns().length; i++ ) { + final ColumnResult columnMapping = mappingAnnotation.columns()[i]; + columnResultMappings.add( + new JpaColumnResultMapping( columnMapping.name(), columnMapping.type() ) + ); + } + } + + return new SqlResultSetMappingDefinition( + mappingAnnotation.name(), + columnResultMappings, + context + ); + } + + private final String mappingName; + + private final List columnResultMappings; + + private SqlResultSetMappingDefinition( + String mappingName, + List columnResultMappings, + MetadataBuildingContext context) { + this.mappingName = mappingName; + this.columnResultMappings = columnResultMappings; + } + + @Override + public String getRegistrationName() { + return mappingName; + } + + @Override + public NamedResultSetMappingMemento resolve(SessionFactoryImplementor factory) { + final List scalarResultBuilders = new ArrayList<>(); + + for ( int i = 0; i < columnResultMappings.size(); i++ ) { + final JpaColumnResultMapping resultMapping = columnResultMappings.get( i ); + scalarResultBuilders.add( resultMapping.resolve( factory ) ); + } + + return new NamedResultSetMappingMementoImpl( + mappingName, + scalarResultBuilders, + factory + ); + } + + + /** + * @see javax.persistence.ColumnResult + */ + private static class JpaColumnResultMapping implements ResultMapping { + private final String columnName; + private final Class explicitJavaType; + + public JpaColumnResultMapping(String columnName, Class explicitJavaType) { + this.columnName = columnName; + this.explicitJavaType = explicitJavaType == void.class + ? null + : explicitJavaType; + } + + public String getColumnName() { + return columnName; + } + + public Class getExplicitJavaType() { + return explicitJavaType; + } + + @Override + public ScalarResultBuilder resolve(SessionFactoryImplementor factory) { + if ( explicitJavaType != null ) { + final JavaTypeDescriptor jtd = factory.getTypeConfiguration() + .getJavaTypeDescriptorRegistry() + .getDescriptor( explicitJavaType ); + + BootLogging.LOGGER.debugf( "ColumnResult explicit type resolved to : " + jtd ); + + return new StandardScalarResultBuilder( columnName, jtd ); + } + + return new StandardScalarResultBuilder( columnName ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java index bd52abf2c8..bf331eaada 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java @@ -18,6 +18,10 @@ import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractNamedQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractNamedQueryDefinition.java index 5d7d069e11..8bb2656d5d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractNamedQueryDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractNamedQueryDefinition.java @@ -12,6 +12,7 @@ import java.util.Map; import org.hibernate.CacheMode; import org.hibernate.FlushMode; import org.hibernate.LockOptions; +import org.hibernate.boot.query.NamedQueryDefinition; /** * @author Steve Ebersole @@ -105,134 +106,4 @@ public abstract class AbstractNamedQueryDefinition implements NamedQueryDefiniti return hints; } - protected static abstract class AbstractBuilder { - private final String name; - - private Boolean cacheable; - private String cacheRegion; - private CacheMode cacheMode; - - private FlushMode flushMode; - private Boolean readOnly; - - private LockOptions lockOptions; - - private Integer timeout; - private Integer fetchSize; - - private String comment; - - private Map hints; - - public AbstractBuilder(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - protected abstract T getThis(); - - public T setCacheable(Boolean cacheable) { - this.cacheable = cacheable; - return getThis(); - } - - public T setCacheRegion(String cacheRegion) { - this.cacheRegion = cacheRegion; - return getThis(); - } - - public T setCacheMode(CacheMode cacheMode) { - this.cacheMode = cacheMode; - return getThis(); - } - - public T setLockOptions(LockOptions lockOptions) { - this.lockOptions = lockOptions; - return getThis(); - } - - public T setTimeout(Integer timeout) { - this.timeout = timeout; - return getThis(); - } - - public T setFlushMode(FlushMode flushMode) { - this.flushMode = flushMode; - return getThis(); - } - - public T setReadOnly(Boolean readOnly) { - this.readOnly = readOnly; - return getThis(); - } - - public T setFetchSize(Integer fetchSize) { - this.fetchSize = fetchSize; - return getThis(); - } - - public T setComment(String comment) { - this.comment = comment; - return getThis(); - } - - public Boolean getCacheable() { - return cacheable; - } - - public String getCacheRegion() { - return cacheRegion; - } - - public CacheMode getCacheMode() { - return cacheMode; - } - - public FlushMode getFlushMode() { - return flushMode; - } - - public Boolean getReadOnly() { - return readOnly; - } - - public LockOptions getLockOptions() { - return lockOptions; - } - - public Integer getTimeout() { - return timeout; - } - - public Integer getFetchSize() { - return fetchSize; - } - - public String getComment() { - return comment; - } - - public void addHint(String name, Object value) { - if ( hints == null ) { - hints = new HashMap<>(); - } - hints.put( name, value ); - } - - public T addHints(Map hintsMap) { - if ( hints == null ) { - hints = new HashMap<>(); - } - hints.putAll( hintsMap ); - - return getThis(); - } - - public Map getHints() { - return hints; - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/HbmResultSetMappingDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/HbmResultSetMappingDefinition.java deleted file mode 100644 index 0ba86627fe..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/HbmResultSetMappingDefinition.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.boot.spi; - -import java.util.List; - -import org.hibernate.LockMode; -import org.hibernate.NotYetImplementedFor6Exception; -import org.hibernate.boot.MappingException; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryCollectionLoadReturnType; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryJoinReturnType; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType; -import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType; -import org.hibernate.boot.model.source.internal.hbm.HbmLocalMetadataBuildingContext; - -/** - * Boot-time descriptor of a result-set-mapping as defined in an `hbm.xml` file - * either implicitly or explicitly - * - * @see org.hibernate.Session#createNativeQuery(String, String) - * @see org.hibernate.Session#createStoredProcedureCall(String, String[]) - * @see org.hibernate.Session#createStoredProcedureCall(String, String[]) - * - * @author Steve Ebersole - */ -public interface HbmResultSetMappingDefinition extends NamedResultSetMappingDefinition { - - class Builder { - private final String registrationName; - - private RootEntityMappingDefinition rootEntityReturn; - private RootCollectionMappingDefinition rootCollectionReturn; - private List joinReturns; - private List rootScalarReturns; - - public Builder(String queryRegistrationName) { - this.registrationName = queryRegistrationName; - } - - public String getRegistrationName() { - return registrationName; - } - - public Builder addReturn(JaxbHbmNativeQueryScalarReturnType returnMapping) { - throw new NotYetImplementedFor6Exception(); - } - - public Builder addReturn(JaxbHbmNativeQueryReturnType returnMapping) { - throw new NotYetImplementedFor6Exception(); - } - - public void addReturn(JaxbHbmNativeQueryJoinReturnType returnMapping) { - throw new NotYetImplementedFor6Exception(); - } - - public void addReturn(JaxbHbmNativeQueryCollectionLoadReturnType returnMapping) { - throw new NotYetImplementedFor6Exception(); - } - - public boolean hasAnyReturns() { - return rootEntityReturn != null || rootCollectionReturn != null || rootScalarReturns != null; - } - - public HbmResultSetMappingDefinition build(HbmLocalMetadataBuildingContext context) { - if ( rootCollectionReturn != null - && ( rootEntityReturn != null || rootScalarReturns != null ) ) { - throw new MappingException( - "HBM return-collection ResultSet mapping cannot define an entity or scalar returns : " + registrationName, - context.getOrigin() - ); - } - - if ( joinReturns != null ) { - if ( rootEntityReturn == null && rootCollectionReturn == null ) { - throw new MappingException( - "HBM return-join ResultSet mapping must be used in conjunction with root entity or collection return : " + registrationName, - context.getOrigin() - ); - } - } - - throw new NotYetImplementedFor6Exception(); - } - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // `hbm.xml` returns - - /** - * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryReturnType - */ - interface RootEntityMappingDefinition { - String getEntityName(); - - String getSqlAlias(); - - List getProperties(); - - String getDiscriminatorColumnName(); - - LockMode getLockMode(); - } - - /** - * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryPropertyReturnType - */ - interface HbmPropertyMappingDefinition { - String getPropertyPath(); - List getColumnNames(); - } - - /** - * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryJoinReturnType - */ - interface JoinMappingDefinition { - String getJoinedPropertyPath(); - - String getSqlAlias(); - - List getProperties(); - - LockMode getLockMode(); - } - - /** - * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryCollectionLoadReturnType - */ - interface RootCollectionMappingDefinition { - String getCollectionRole(); - - String getSqlAlias(); - - List getProperties(); - - LockMode getLockMode(); - } - - /** - * @see org.hibernate.boot.jaxb.hbm.spi.JaxbHbmNativeQueryScalarReturnType - */ - interface ScalarMappingDefinition { - String getColumnName(); - String getTypeName(); - } - - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // JPA returns - - /** - * @see javax.persistence.ColumnResult - */ - interface JpaColumnResult { - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java index c66a3f49ed..fe3d7cba10 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java @@ -30,6 +30,10 @@ import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.source.spi.LocalMetadataBuildingContext; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.cfg.AnnotatedClassType; import org.hibernate.cfg.AttributeConverterDefinition; import org.hibernate.cfg.JPAIndexHolder; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedNativeQueryDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedNativeQueryDefinition.java deleted file mode 100644 index 8602820d42..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/NamedNativeQueryDefinition.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.boot.spi; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.query.sql.spi.NamedNativeQueryMemento; - -/** - * Boot-time descriptor of a named native query, as defined in - * annotations or xml - * - * @see javax.persistence.NamedNativeQuery - * @see org.hibernate.annotations.NamedNativeQuery - * - * @author Steve Ebersole - * @author Gavin King - */ -public interface NamedNativeQueryDefinition extends NamedQueryDefinition { - String getSqlQueryString(); - - String getResultSetMappingName(); - String getResultSetMappingClassName(); - - @Override - NamedNativeQueryMemento resolve(SessionFactoryImplementor factory); - - class Builder extends AbstractNamedQueryDefinition.AbstractBuilder { - private String sqlString; - - private String resultSetMappingName; - private String resultSetMappingClassName; - - private Set querySpaces; - - private Map parameterTypes; - - public Builder(String name) { - super( name ); - } - - public Builder setSqlString(String sqlString) { - this.sqlString = sqlString; - return getThis(); - } - - public NamedNativeQueryDefinition build() { - return new NamedNativeQueryDefinitionImpl( - getName(), - sqlString, - resultSetMappingName, - resultSetMappingClassName, - getQuerySpaces(), - getCacheable(), - getCacheRegion(), - getCacheMode(), - getFlushMode(), - getReadOnly(), - getTimeout(), - getFetchSize(), - getComment(), - getHints() - ); - } - - @Override - protected Builder getThis() { - return this; - } - - public Set getQuerySpaces() { - return querySpaces; - } - - public Builder addSynchronizedQuerySpaces(Set querySpaces) { - if ( querySpaces == null || querySpaces.isEmpty() ) { - return this; - } - - if ( this.querySpaces == null ) { - this.querySpaces = new HashSet<>(); - } - - this.querySpaces.addAll( querySpaces ); - - return getThis(); - } - - public Builder addSynchronizedQuerySpace(String space) { - if ( this.querySpaces == null ) { - this.querySpaces = new HashSet<>(); - } - this.querySpaces.add( space ); - return getThis(); - } - - public Builder setQuerySpaces(Set spaces) { - this.querySpaces = spaces; - return this; - } - - public Builder setResultSetMappingName(String resultSetMappingName) { - this.resultSetMappingName = resultSetMappingName; - return this; - } - - public Builder setResultSetMappingClassName(String resultSetMappingClassName) { - this.resultSetMappingClassName = resultSetMappingClassName; - return this; - } - - public void addParameterTypeHint(String name, String type) { - if ( parameterTypes == null ) { - parameterTypes = new HashMap<>(); - } - - parameterTypes.put( name, type ); - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index 048257c8f7..ca19d4973a 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -43,10 +43,10 @@ import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; -import org.hibernate.boot.spi.NamedProcedureCallDefinition; -import org.hibernate.boot.spi.NamedResultSetMappingDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedProcedureCallDefinition; +import org.hibernate.boot.query.NamedResultSetMappingDefinition; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; import org.hibernate.internal.CoreLogging; diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java index 772e0ae6d0..4841529d26 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java @@ -23,10 +23,10 @@ import org.hibernate.annotations.CacheModeType; import org.hibernate.annotations.FlushModeType; import org.hibernate.annotations.QueryHints; import org.hibernate.boot.internal.NamedHqlQueryDefinitionImpl; -import org.hibernate.boot.internal.NamedNativeQueryDefinitionImpl; +import org.hibernate.boot.query.NamedNativeQueryDefinitionBuilder; import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; import org.hibernate.cfg.BinderHelper; import org.hibernate.internal.CoreMessageLogger; @@ -105,7 +105,7 @@ public abstract class QueryBinder { ? null : queryAnn.resultClass().getName(); - final NamedNativeQueryDefinition.Builder builder = new NamedNativeQueryDefinitionImpl.Builder( registrationName ) + final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( registrationName ) .setSqlString( queryString ) .setResultSetMappingName( resultSetMappingName ) .setResultSetMappingClassName( resultSetMappingClassName ) @@ -154,7 +154,7 @@ public abstract class QueryBinder { ? null : queryAnn.resultClass().getName(); - final NamedNativeQueryDefinition.Builder builder = new NamedNativeQueryDefinitionImpl.Builder( registrationName ) + final NamedNativeQueryDefinitionBuilder builder = new NamedNativeQueryDefinitionBuilder( registrationName ) .setSqlString( queryAnn.query() ) .setResultSetMappingName( resultSetMappingName ) .setResultSetMappingClassName( resultSetMappingClassName ) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java index 74857b4ef8..71c3dee4d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java @@ -22,6 +22,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; +import org.hibernate.boot.query.SqlResultSetMappingDefinition; /** * @author Emmanuel Bernard diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SqlResultSetMappingDefinition.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SqlResultSetMappingDefinition.java deleted file mode 100644 index 32cb0ef5a8..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/SqlResultSetMappingDefinition.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.cfg.annotations; - -import javax.persistence.SqlResultSetMapping; - -import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.boot.spi.NamedResultSetMappingDefinition; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.query.internal.NamedResultSetMappingMementoImpl; -import org.hibernate.query.named.NamedResultSetMappingMemento; - -/** - * @author Steve Ebersole - */ -public class SqlResultSetMappingDefinition implements NamedResultSetMappingDefinition { - public static SqlResultSetMappingDefinition from( - SqlResultSetMapping mappingAnnotation, - MetadataBuildingContext context) { - return new SqlResultSetMappingDefinition( mappingAnnotation.name(), context ); - } - - private final String mappingName; - - private SqlResultSetMappingDefinition(String mappingName, MetadataBuildingContext context) { - this.mappingName = mappingName; - } - - @Override - public String getRegistrationName() { - return mappingName; - } - - @Override - public NamedResultSetMappingMemento resolve(SessionFactoryImplementor factory) { - return new NamedResultSetMappingMementoImpl( mappingName, factory ); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index fd2b9d6bbb..505ddfd97f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -517,8 +517,8 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { } @Override - public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) { - return delegate.createNativeQuery( sqlString, resultSetMapping ); + public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName) { + return delegate.createNativeQuery( sqlString, resultSetMappingName ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java index 185dd0937f..0d5c3f5e45 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java @@ -102,7 +102,7 @@ public interface SessionImplementor extends Session, SharedSessionContractImplem NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass); @Override - NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping); + NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName); @Override NativeQueryImplementor getNamedNativeQuery(String name); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index e9bd15e60c..3e732228b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -51,6 +51,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.transaction.internal.TransactionImpl; import org.hibernate.engine.transaction.spi.TransactionImplementor; import org.hibernate.id.uuid.StandardRandomStrategy; +import org.hibernate.internal.util.StringHelper; import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.Work; import org.hibernate.jdbc.WorkExecutorVisitable; @@ -62,6 +63,7 @@ import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.query.Query; import org.hibernate.query.hql.spi.HqlQueryImplementor; import org.hibernate.query.hql.spi.NamedHqlQueryMemento; +import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryInterpretationCache; @@ -690,34 +692,34 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont } @Override - public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping) { -// checkOpen(); -// pulseTransactionCoordinator(); -// delayedAfterCompletion(); -// -// final NativeQueryImplementor query; -// try { -// if ( StringHelper.isNotEmpty( resultSetMapping ) ) { -// final ResultSetMappingDescriptor resultSetMappingDescriptor = getFactory().getQueryEngine() -// .getNamedQueryRepository() -// .getResultSetMappingDescriptor( resultSetMapping ); -// -// if ( resultSetMappingDescriptor == null ) { -// throw new HibernateException( "Could not resolve specified result-set mapping name : " + resultSetMapping ); -// } -// -// query = new NativeQueryImpl( sqlString, resultSetMappingDescriptor, this ); -// } -// else { -// query = new NativeQueryImpl( sqlString, this ); -// } -// } -// catch (RuntimeException he) { -// throw getExceptionConverter().convert( he ); -// } -// -// return query; - throw new NotYetImplementedFor6Exception( getClass() ); + public NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName) { + checkOpen(); + pulseTransactionCoordinator(); + delayedAfterCompletion(); + + final NativeQueryImplementor query; + try { + if ( StringHelper.isNotEmpty( resultSetMappingName ) ) { + final NamedResultSetMappingMemento resultSetMappingMemento = getFactory().getQueryEngine() + .getNamedQueryRepository() + .getResultSetMappingMemento( resultSetMappingName ); + + if ( resultSetMappingMemento == null ) { + throw new HibernateException( "Could not resolve specified result-set mapping name : " + resultSetMappingName ); + } + + query = new NativeQueryImpl( sqlString, resultSetMappingMemento, this ); + } + else { + query = new NativeQueryImpl( sqlString, this ); + } + } + catch (RuntimeException he) { + throw getExceptionConverter().convert( he ); + } + + return query; +// throw new NotYetImplementedFor6Exception( getClass() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java b/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java index 78ab4b5744..442eaa2c99 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java @@ -118,14 +118,14 @@ public interface QueryProducer { * implicit mapping to the specified Java type. * * @param sqlString Native (SQL) query string - * @param resultSetMapping The explicit (named) result mapping + * @param resultSetMappingName The explicit result mapping name * * @return The NativeQuery instance for manipulation and execution * * @see javax.persistence.EntityManager#createNativeQuery(String,Class) * @see javax.persistence.SqlResultSetMapping */ - NativeQuery createNativeQuery(String sqlString, String resultSetMapping); + NativeQuery createNativeQuery(String sqlString, String resultSetMappingName); /** * Get a NativeQuery instance for a named native SQL query diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java index fcc744da05..1295e459b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/spi/NamedHqlQueryMemento.java @@ -10,7 +10,7 @@ import java.util.HashMap; import java.util.Map; import org.hibernate.LockOptions; -import org.hibernate.boot.spi.NamedHqlQueryDefinition; +import org.hibernate.boot.query.NamedHqlQueryDefinition; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.named.AbstractNamedQueryMemento; 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 49e6f7896d..51b6cf64b7 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,21 +6,30 @@ */ package org.hibernate.query.internal; +import java.util.List; import java.util.function.Consumer; -import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.results.ResultSetMapping; +import org.hibernate.query.results.ScalarResultBuilder; /** + * Standard `NamedResultSetMappingMemento` implementation + * * @author Steve Ebersole */ public class NamedResultSetMappingMementoImpl implements NamedResultSetMappingMemento { private final String name; - public NamedResultSetMappingMementoImpl(String name, SessionFactoryImplementor factory) { + private final List scalarResultBuilders; + + public NamedResultSetMappingMementoImpl( + String name, + List scalarResultBuilders, + SessionFactoryImplementor factory) { this.name = name; + this.scalarResultBuilders = scalarResultBuilders; } @Override @@ -33,6 +42,16 @@ public class NamedResultSetMappingMementoImpl implements NamedResultSetMappingMe ResultSetMapping resultSetMapping, Consumer querySpaceConsumer, SessionFactoryImplementor sessionFactory) { - throw new NotYetImplementedFor6Exception( getClass() ); + scalarResultBuilders.forEach( + builder -> resultSetMapping.addResultBuilder( + (jdbcResultsMetadata, legacyFetchResolver, sqlSelectionConsumer, sessionFactory1) -> + builder.buildReturn( + jdbcResultsMetadata, + legacyFetchResolver, + sqlSelectionConsumer, + sessionFactory + ) + ) + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/StandardScalarResultBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/results/StandardScalarResultBuilder.java index 40e6c36c54..c135165118 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/StandardScalarResultBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/StandardScalarResultBuilder.java @@ -38,7 +38,7 @@ public class StandardScalarResultBuilder implements ScalarResultBuilder { this.explicitJavaTypeDescriptor = null; } - StandardScalarResultBuilder(String explicitName, BasicType explicitType) { + public StandardScalarResultBuilder(String explicitName, BasicType explicitType) { assert explicitName != null; this.explicitName = explicitName; @@ -48,7 +48,7 @@ public class StandardScalarResultBuilder implements ScalarResultBuilder { this.explicitJavaTypeDescriptor = null; } - StandardScalarResultBuilder(String explicitName, JavaTypeDescriptor explicitJavaTypeDescriptor) { + public StandardScalarResultBuilder(String explicitName, JavaTypeDescriptor explicitJavaTypeDescriptor) { assert explicitName != null; this.explicitName = explicitName; diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java index 763393ae3f..9ac6e87aa2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java @@ -52,7 +52,7 @@ public interface QueryProducerImplementor extends QueryProducer { NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass); @Override - NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMapping); + NativeQueryImplementor createNativeQuery(String sqlString, String resultSetMappingName); @Override NativeQueryImplementor getNamedNativeQuery(String name); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index 12e5d79fe5..953094998a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -44,6 +44,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.graph.GraphSemantic; import org.hibernate.graph.RootGraph; import org.hibernate.graph.spi.RootGraphImplementor; +import org.hibernate.internal.AbstractSharedSessionContract; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.model.domain.AllowableParameterType; @@ -57,6 +58,7 @@ import org.hibernate.query.TupleTransformer; import org.hibernate.query.internal.ParameterMetadataImpl; import org.hibernate.query.internal.QueryOptionsImpl; import org.hibernate.query.internal.QueryParameterBindingsImpl; +import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.results.Builders; import org.hibernate.query.results.EntityResultBuilder; import org.hibernate.query.results.LegacyFetchBuilder; @@ -159,6 +161,22 @@ public class NativeQueryImpl // todo (6.0) : relatedly, does `resultSetMappingName` come from `NamedNativeQuery#resultSetMapping`? } + public NativeQueryImpl( + String sqlString, + NamedResultSetMappingMemento resultSetMappingMemento, + AbstractSharedSessionContract session) { + super( session ); + + this.sqlString = sqlString; + resultSetMappingMemento.resolve( resultSetMapping, (s) -> {}, getSessionFactory() ); + + final ParameterInterpretation parameterInterpretation = resolveParameterInterpretation( session ); + + this.parameterMetadata = parameterInterpretation.toParameterMetadata( session ); + this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters(); + this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() ); + } + private ParameterInterpretation resolveParameterInterpretation(SharedSessionContractImplementor session) { final SessionFactoryImplementor sessionFactory = session.getFactory(); final QueryEngine queryEngine = sessionFactory.getQueryEngine(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java index 9a72cb5564..e22647045e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java @@ -9,7 +9,7 @@ package org.hibernate.query.sql.spi; import java.util.Set; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.named.AbstractNamedQueryMemento; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleEntityWithNamedMappings.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleEntityWithNamedMappings.java index ea143c9bee..6cf1e157fd 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleEntityWithNamedMappings.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleEntityWithNamedMappings.java @@ -19,6 +19,13 @@ import javax.persistence.SqlResultSetMapping; name = "name", columns = @ColumnResult( name = "name" ) ) +@SqlResultSetMapping( + name = "id_name", + columns = { + @ColumnResult( name = "id" ), + @ColumnResult( name = "name" ) + } +) public class SimpleEntityWithNamedMappings { @Id private Integer id; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleNamedMappingTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleNamedMappingTests.java index 74d08aba98..cdd2d2f89b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleNamedMappingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/SimpleNamedMappingTests.java @@ -13,7 +13,6 @@ import org.hibernate.query.results.ResultSetMappingImpl; import org.hibernate.query.spi.QueryEngine; import org.hibernate.testing.orm.junit.DomainModel; -import org.hibernate.testing.orm.junit.FailureExpected; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.junit.jupiter.api.Test; @@ -28,8 +27,7 @@ import static org.hamcrest.MatcherAssert.assertThat; @SessionFactory public class SimpleNamedMappingTests { @Test - @FailureExpected( reason = "Memento-ization of row-reader not yet implemented" ) - public void testMapping(SessionFactoryScope sessionFactoryScope) { + public void testMappingResolution(SessionFactoryScope sessionFactoryScope) { final QueryEngine queryEngine = sessionFactoryScope.getSessionFactory().getQueryEngine(); final NamedQueryRepository namedQueryRepository = queryEngine.getNamedQueryRepository(); final NamedResultSetMappingMemento mappingMemento = namedQueryRepository.getResultSetMappingMemento( "name" ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/UsageTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/UsageTests.java new file mode 100644 index 0000000000..3dc720619c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/named/resultmapping/UsageTests.java @@ -0,0 +1,70 @@ +/* + * 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.named.resultmapping; + +import java.time.Instant; + +import org.hibernate.query.named.NamedResultSetMappingMemento; +import org.hibernate.query.sql.spi.NativeQueryImplementor; + +import org.hibernate.testing.orm.domain.StandardDomainModel; +import org.hibernate.testing.orm.domain.helpdesk.Incident; +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.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +/** + * @author Steve Ebersole + */ +@DomainModel( standardModels = StandardDomainModel.HELPDESK ) +@SessionFactory +public class UsageTests { + @Test + public void testSimpleScalarMappings(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + // make sure it is in the repository + final NamedResultSetMappingMemento mappingMemento = session.getSessionFactory() + .getQueryEngine() + .getNamedQueryRepository() + .getResultSetMappingMemento( "incident_summary" ); + assertThat( mappingMemento, notNullValue() ); + + // apply it to a native-query + final String qryString = "select id, description, reported from incident"; + session.createNativeQuery( qryString, "incident_summary" ).list(); + + // todo (6.0) : should also try executing the ProcedureCall once that functionality is implemented + session.createStoredProcedureCall( "abc", "incident_summary" ); + } + ); + } + + @BeforeEach + public void prepareData(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.save( new Incident( 1, "test", Instant.now() ) ); + } + ); + } + + @AfterEach + public void cleanUpData(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createQuery( "delete Incident" ).executeUpdate(); + } + ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/hbm/query/QueryReturnTest.java b/hibernate-core/src/test/java/org/hibernate/test/hbm/query/QueryReturnTest.java index 83a971f9b0..1ffaff9e7d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hbm/query/QueryReturnTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hbm/query/QueryReturnTest.java @@ -8,10 +8,8 @@ import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; -import org.hibernate.boot.spi.NamedNativeQueryDefinition; +import org.hibernate.boot.query.NamedNativeQueryDefinition; import org.hibernate.engine.jdbc.ReaderInputStream; -import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; -import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseUnitTestCase; diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/domain/helpdesk/Incident.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/domain/helpdesk/Incident.java index 873fde41a9..3496954f1e 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/orm/domain/helpdesk/Incident.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/domain/helpdesk/Incident.java @@ -7,21 +7,54 @@ package org.hibernate.testing.orm.domain.helpdesk; import java.time.Instant; +import javax.persistence.ColumnResult; import javax.persistence.Entity; import javax.persistence.Id; +import javax.persistence.SqlResultSetMapping; /** * @author Steve Ebersole */ @Entity +@SqlResultSetMapping( + name = "incident_summary", + columns = { + @ColumnResult( name = "id" ), + @ColumnResult( name = "description" ), + @ColumnResult( name = "reported", type = Instant.class ) + } +) public class Incident { private Integer id; + private String description; private Instant reported; private Instant effectiveStart; private Instant effectiveEnd; + public Incident() { + } + + public Incident(Integer id, String description, Instant reported) { + this.id = id; + this.description = description; + this.reported = reported; + } + + public Incident( + Integer id, + String description, + Instant reported, + Instant effectiveStart, + Instant effectiveEnd) { + this.id = id; + this.description = description; + this.reported = reported; + this.effectiveStart = effectiveStart; + this.effectiveEnd = effectiveEnd; + } + @Id public Integer getId() { return id; @@ -31,6 +64,14 @@ public class Incident { this.id = id; } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public Instant getReported() { return reported; }