HHH-16226 - Introduce JdbcValuesMappingProducerProvider
This commit is contained in:
parent
88ed4fdb91
commit
a36f6aa736
|
@ -23,7 +23,9 @@ import org.hibernate.procedure.internal.NamedCallableQueryMementoImpl;
|
|||
import org.hibernate.procedure.internal.Util;
|
||||
import org.hibernate.procedure.spi.NamedCallableQueryMemento;
|
||||
import org.hibernate.procedure.spi.ParameterStrategy;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
|
||||
import jakarta.persistence.NamedStoredProcedureQuery;
|
||||
import jakarta.persistence.ParameterMode;
|
||||
|
@ -86,7 +88,7 @@ public class NamedProcedureCallDefinitionImpl implements NamedProcedureCallDefin
|
|||
final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
|
||||
final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;
|
||||
|
||||
ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl( registeredName );
|
||||
final ResultSetMapping resultSetMapping = buildResultSetMapping( registeredName, sessionFactory );
|
||||
|
||||
if ( specifiesResultClasses ) {
|
||||
Util.resolveResultSetMappingClasses(
|
||||
|
@ -125,6 +127,13 @@ public class NamedProcedureCallDefinitionImpl implements NamedProcedureCallDefin
|
|||
);
|
||||
}
|
||||
|
||||
private ResultSetMapping buildResultSetMapping(String registeredName, SessionFactoryImplementor sessionFactory) {
|
||||
return sessionFactory
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcValuesMappingProducerProvider.class )
|
||||
.buildResultSetMapping( registeredName, false, sessionFactory );
|
||||
}
|
||||
|
||||
static class ParameterDefinitions {
|
||||
private final ParameterStrategy parameterStrategy;
|
||||
private final ParameterDefinition<?>[] parameterDefinitions;
|
||||
|
|
|
@ -51,7 +51,6 @@ import org.hibernate.query.QueryParameter;
|
|||
import org.hibernate.query.internal.QueryOptionsImpl;
|
||||
import org.hibernate.query.procedure.ProcedureParameter;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.query.spi.AbstractQuery;
|
||||
import org.hibernate.query.spi.MutableQueryOptions;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
|
@ -94,6 +93,7 @@ import jakarta.persistence.TransactionRequiredException;
|
|||
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CALLABLE_FUNCTION;
|
||||
import static org.hibernate.procedure.internal.NamedCallableQueryMementoImpl.ParameterMementoImpl.fromRegistration;
|
||||
import static org.hibernate.query.results.ResultSetMapping.resolveResultSetMapping;
|
||||
|
||||
/**
|
||||
* Standard implementation of {@link ProcedureCall}
|
||||
|
@ -134,7 +134,7 @@ public class ProcedureCallImpl<R>
|
|||
this.parameterMetadata = new ProcedureParameterMetadataImpl();
|
||||
this.paramBindings = new ProcedureParamBindings( parameterMetadata, getSessionFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( procedureName, true );
|
||||
this.resultSetMapping = resolveResultSetMapping( procedureName, true, session.getSessionFactory() );
|
||||
|
||||
this.synchronizedQuerySpaces = null;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultClasses );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappingClasses(
|
||||
resultClasses,
|
||||
|
@ -193,7 +193,7 @@ public class ProcedureCallImpl<R>
|
|||
this.synchronizedQuerySpaces = new HashSet<>();
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappingNames(
|
||||
resultSetMappingNames,
|
||||
|
@ -219,7 +219,7 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( memento.getRegistrationName() );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( memento.getRegistrationName(), session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
memento.getResultSetMappingNames(),
|
||||
|
@ -252,7 +252,7 @@ public class ProcedureCallImpl<R>
|
|||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultTypes );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
null,
|
||||
|
@ -279,7 +279,7 @@ public class ProcedureCallImpl<R>
|
|||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = new ResultSetMappingImpl( mappingId );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
resultSetMappingNames,
|
||||
|
|
|
@ -6,21 +6,22 @@
|
|||
*/
|
||||
package org.hibernate.query.results;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.named.NamedResultSetMappingMemento;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
|
||||
/**
|
||||
* Acts as the {@link JdbcValuesMappingProducer} for {@link NativeQuery}
|
||||
* or {@link org.hibernate.procedure.ProcedureCall} / {@link jakarta.persistence.StoredProcedureQuery}
|
||||
* instances.
|
||||
*
|
||||
* Can be defined<ul>
|
||||
* instances. These mappings can be defined<ul>
|
||||
* <li>
|
||||
* statically via {@link jakarta.persistence.SqlResultSetMapping} or `hbm.xml` mapping
|
||||
* </li>
|
||||
|
@ -39,13 +40,64 @@ import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
|||
*/
|
||||
@Incubating
|
||||
public interface ResultSetMapping extends JdbcValuesMappingProducer {
|
||||
/**
|
||||
* An identifier for the mapping
|
||||
*/
|
||||
String getMappingIdentifier();
|
||||
|
||||
/**
|
||||
* Indicates whether the mapping is dynamic per {@link ResultSetMapping}
|
||||
*/
|
||||
boolean isDynamic();
|
||||
|
||||
/**
|
||||
* The number of result builders currently associated with this mapping
|
||||
*/
|
||||
int getNumberOfResultBuilders();
|
||||
|
||||
/**
|
||||
* The result builders currently associated with this mapping
|
||||
*/
|
||||
List<ResultBuilder> getResultBuilders();
|
||||
|
||||
/**
|
||||
* Visit each result builder
|
||||
*/
|
||||
void visitResultBuilders(BiConsumer<Integer, ResultBuilder> resultBuilderConsumer);
|
||||
|
||||
/**
|
||||
* Visit the "legacy" fetch builders.
|
||||
* <p/>
|
||||
* Historically these mappings in Hibernate were defined such that results and fetches are
|
||||
* unaware of each other. So while {@link ResultBuilder} encapsulates the fetches (see
|
||||
* {@link ResultBuilder#visitFetchBuilders}), fetches defined in the legacy way are unassociated
|
||||
* to their "parent".
|
||||
*/
|
||||
void visitLegacyFetchBuilders(Consumer<DynamicFetchBuilderLegacy> resultBuilderConsumer);
|
||||
|
||||
/**
|
||||
* Add a builder
|
||||
*/
|
||||
void addResultBuilder(ResultBuilder resultBuilder);
|
||||
|
||||
/**
|
||||
* Add a legacy fetch builder
|
||||
*/
|
||||
void addLegacyFetchBuilder(DynamicFetchBuilderLegacy fetchBuilder);
|
||||
|
||||
/**
|
||||
* Create a memento from this mapping.
|
||||
*/
|
||||
NamedResultSetMappingMemento toMemento(String name);
|
||||
|
||||
static ResultSetMapping resolveResultSetMapping(String name, SessionFactoryImplementor sessionFactory) {
|
||||
return resolveResultSetMapping( name, false, sessionFactory );
|
||||
}
|
||||
|
||||
static ResultSetMapping resolveResultSetMapping(String name, boolean isDynamic, SessionFactoryImplementor sessionFactory) {
|
||||
return sessionFactory
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcValuesMappingProducerProvider.class )
|
||||
.buildResultSetMapping( name, isDynamic, sessionFactory );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,16 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMappingIdentifier(){
|
||||
return mappingIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return isDynamic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfResultBuilders() {
|
||||
return resultBuilders == null ? 0 : resultBuilders.size();
|
||||
|
@ -156,10 +166,6 @@ public class ResultSetMappingImpl implements ResultSetMapping {
|
|||
}
|
||||
}
|
||||
|
||||
public String getMappingIdentifier(){
|
||||
return mappingIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAffectedTableNames(Set<String> affectedTableNames, SessionFactoryImplementor sessionFactory) {
|
||||
if ( StringHelper.isEmpty( mappingIdentifier ) ) {
|
||||
|
|
|
@ -57,7 +57,6 @@ import org.hibernate.query.named.NamedResultSetMappingMemento;
|
|||
import org.hibernate.query.results.Builders;
|
||||
import org.hibernate.query.results.ResultBuilder;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.dynamic.DynamicResultBuilderEntityStandard;
|
||||
import org.hibernate.query.results.dynamic.DynamicResultBuilderInstantiation;
|
||||
|
@ -118,7 +117,7 @@ public class NativeQueryImpl<R>
|
|||
private final List<ParameterOccurrence> parameterOccurrences;
|
||||
private final QueryParameterBindings parameterBindings;
|
||||
|
||||
private final ResultSetMappingImpl resultSetMapping;
|
||||
private final ResultSetMapping resultSetMapping;
|
||||
private final boolean resultMappingSuppliedToCtor;
|
||||
|
||||
private final QueryOptionsImpl queryOptions = new QueryOptionsImpl();
|
||||
|
@ -137,13 +136,13 @@ public class NativeQueryImpl<R>
|
|||
memento,
|
||||
() -> {
|
||||
if ( memento.getResultMappingName() != null ) {
|
||||
return new ResultSetMappingImpl( memento.getResultMappingName() );
|
||||
return buildResultSetMapping( memento.getResultMappingName(), false, session );
|
||||
}
|
||||
else if ( memento.getResultMappingClass() != null ) {
|
||||
return new ResultSetMappingImpl( memento.getResultMappingClass().getName() );
|
||||
return buildResultSetMapping( memento.getResultMappingClass().getName(), false, session );
|
||||
}
|
||||
|
||||
return new ResultSetMappingImpl( memento.getSqlString() );
|
||||
return buildResultSetMapping( memento.getSqlString(), false, session );
|
||||
},
|
||||
(resultSetMapping, querySpaceConsumer, context ) -> {
|
||||
if ( memento.getResultMappingName() != null ) {
|
||||
|
@ -176,14 +175,21 @@ public class NativeQueryImpl<R>
|
|||
@FunctionalInterface
|
||||
private interface ResultSetMappingHandler {
|
||||
boolean resolveResultSetMapping(
|
||||
ResultSetMappingImpl resultSetMapping,
|
||||
ResultSetMapping resultSetMapping,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context);
|
||||
}
|
||||
|
||||
private static ResultSetMapping buildResultSetMapping(
|
||||
String registeredName,
|
||||
boolean isDynamic,
|
||||
SharedSessionContractImplementor session) {
|
||||
return ResultSetMapping.resolveResultSetMapping( registeredName, isDynamic, session.getFactory() );
|
||||
}
|
||||
|
||||
public NativeQueryImpl(
|
||||
NamedNativeQueryMemento memento,
|
||||
Supplier<ResultSetMappingImpl> resultSetMappingCreator,
|
||||
Supplier<ResultSetMapping> resultSetMappingCreator,
|
||||
ResultSetMappingHandler resultSetMappingHandler,
|
||||
SharedSessionContractImplementor session) {
|
||||
super( session );
|
||||
|
@ -226,7 +232,7 @@ public class NativeQueryImpl<R>
|
|||
memento,
|
||||
() -> {
|
||||
final String mappingIdentifier = resultJavaType != null ? resultJavaType.getName() : null;
|
||||
return new ResultSetMappingImpl( mappingIdentifier );
|
||||
return buildResultSetMapping( mappingIdentifier, false, session );
|
||||
},
|
||||
(resultSetMapping, querySpaceConsumer, context) -> {
|
||||
if ( memento.getResultMappingName() != null ) {
|
||||
|
@ -284,7 +290,7 @@ public class NativeQueryImpl<R>
|
|||
SharedSessionContractImplementor session) {
|
||||
this(
|
||||
memento,
|
||||
() -> new ResultSetMappingImpl( resultSetMappingName ),
|
||||
() -> buildResultSetMapping( resultSetMappingName, false, session ),
|
||||
(resultSetMapping, querySpaceConsumer, context) -> {
|
||||
final NamedResultSetMappingMemento mappingMemento = session.getFactory()
|
||||
.getQueryEngine()
|
||||
|
@ -314,7 +320,7 @@ public class NativeQueryImpl<R>
|
|||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
this.querySpaces = new HashSet<>();
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultSetMappingMemento.getName() );
|
||||
this.resultSetMapping = buildResultSetMapping( resultSetMappingMemento.getName(), false, session );
|
||||
resultSetMappingMemento.resolve(
|
||||
resultSetMapping,
|
||||
this::addSynchronizedQuerySpace,
|
||||
|
@ -379,7 +385,7 @@ public class NativeQueryImpl<R>
|
|||
this.parameterOccurrences = parameterInterpretation.getOrderedParameterOccurrences();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( sqlString, true );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( sqlString, true, session.getFactory() );
|
||||
this.resultMappingSuppliedToCtor = false;
|
||||
}
|
||||
|
||||
|
@ -463,7 +469,7 @@ public class NativeQueryImpl<R>
|
|||
);
|
||||
}
|
||||
|
||||
private Class<?> extractResultClass(ResultSetMappingImpl resultSetMapping) {
|
||||
private Class<?> extractResultClass(ResultSetMapping resultSetMapping) {
|
||||
final List<ResultBuilder> resultBuilders = resultSetMapping.getResultBuilders();
|
||||
if ( resultBuilders.size() == 1 ) {
|
||||
final ResultBuilder resultBuilder = resultBuilders.get( 0 );
|
||||
|
|
|
@ -32,19 +32,20 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.Loadable;
|
||||
import org.hibernate.persister.entity.SQLLoadable;
|
||||
import org.hibernate.query.NativeQuery;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderContainer;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.query.results.FetchBuilder;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.query.results.complete.CompleteResultBuilderCollectionStandard;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderContainer;
|
||||
import org.hibernate.query.results.dynamic.DynamicFetchBuilderLegacy;
|
||||
import org.hibernate.query.results.dynamic.DynamicResultBuilderEntityStandard;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.ComponentType;
|
||||
import org.hibernate.type.EntityType;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
import static org.hibernate.query.results.ResultSetMapping.resolveResultSetMapping;
|
||||
|
||||
|
||||
/**
|
||||
* Responsible for processing the {@link ResultSetMapping} defined by a
|
||||
|
@ -154,7 +155,8 @@ public class ResultSetMappingProcessor implements SQLQueryParser.ParserContext {
|
|||
if ( !queryHadAliases ) {
|
||||
return this.resultSetMapping;
|
||||
}
|
||||
final ResultSetMappingImpl resultSetMapping = new ResultSetMappingImpl( null );
|
||||
|
||||
final ResultSetMapping resultSetMapping = resolveResultSetMapping( null, false, factory );
|
||||
final Set<String> visited = new HashSet<>();
|
||||
this.resultSetMapping.visitResultBuilders(
|
||||
(i, resultBuilder) -> {
|
||||
|
@ -204,7 +206,7 @@ public class ResultSetMappingProcessor implements SQLQueryParser.ParserContext {
|
|||
}
|
||||
|
||||
private void applyFetchBuilder(
|
||||
ResultSetMappingImpl resultSetMapping,
|
||||
ResultSetMapping resultSetMapping,
|
||||
DynamicFetchBuilderLegacy fetchBuilder,
|
||||
Set<String> visited) {
|
||||
if ( !visited.add( fetchBuilder.getTableAlias() ) ) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.property.access.internal.PropertyAccessStrategyResolverInit
|
|||
import org.hibernate.resource.beans.spi.ManagedBeanRegistryInitiator;
|
||||
import org.hibernate.resource.transaction.internal.TransactionCoordinatorBuilderInitiator;
|
||||
import org.hibernate.service.internal.SessionFactoryServiceRegistryFactoryInitiator;
|
||||
import org.hibernate.sql.results.jdbc.internal.JdbcValuesMappingProducerProviderInitiator;
|
||||
import org.hibernate.tool.schema.internal.SchemaManagementToolInitiator;
|
||||
import org.hibernate.tool.schema.internal.script.SqlScriptExtractorInitiator;
|
||||
|
||||
|
@ -95,6 +96,8 @@ public final class StandardServiceInitiators {
|
|||
serviceInitiators.add( ManagedBeanRegistryInitiator.INSTANCE );
|
||||
serviceInitiators.add( EntityCopyObserverFactoryInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( JdbcValuesMappingProducerProviderInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.trimToSize();
|
||||
|
||||
return Collections.unmodifiableList( serviceInitiators );
|
||||
|
|
|
@ -193,6 +193,8 @@ import org.hibernate.sql.model.internal.TableUpdateCustomSql;
|
|||
import org.hibernate.sql.model.internal.TableUpdateStandard;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.jdbc.internal.JdbcValuesMappingProducerStandard;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
import org.hibernate.type.BasicPluralType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
@ -843,10 +845,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
return new JdbcOperationQuerySelect(
|
||||
getSql(),
|
||||
getParameterBinders(),
|
||||
new JdbcValuesMappingProducerStandard(
|
||||
selectStatement.getQuerySpec().getSelectClause().getSqlSelections(),
|
||||
selectStatement.getDomainResultDescriptors()
|
||||
),
|
||||
buildJdbcValuesMappingProducer( selectStatement ),
|
||||
getAffectedTableNames(),
|
||||
getFilterJdbcParameters(),
|
||||
rowsToSkip = getRowsToSkip( selectStatement, getJdbcParameterBindings() ),
|
||||
|
@ -858,6 +857,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
);
|
||||
}
|
||||
|
||||
private JdbcValuesMappingProducer buildJdbcValuesMappingProducer(SelectStatement selectStatement) {
|
||||
final JdbcValuesMappingProducerProvider producerProvider = getSessionFactory()
|
||||
.getServiceRegistry()
|
||||
.getService( JdbcValuesMappingProducerProvider.class );
|
||||
return producerProvider.buildMappingProducer( selectStatement, getSessionFactory() );
|
||||
}
|
||||
|
||||
protected int getRowsToSkip(SelectStatement sqlAstSelect, JdbcParameterBindings jdbcParameterBindings) {
|
||||
if ( hasLimit() ) {
|
||||
if ( offsetParameter != null && needsRowsToSkip() ) {
|
||||
|
|
|
@ -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.sql.results.jdbc.internal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
|
||||
/**
|
||||
* Initiator for {@link JdbcValuesMappingProducerProviderStandard}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcValuesMappingProducerProviderInitiator
|
||||
implements StandardServiceInitiator<JdbcValuesMappingProducerProvider> {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final JdbcValuesMappingProducerProviderInitiator INSTANCE = new JdbcValuesMappingProducerProviderInitiator();
|
||||
|
||||
@Override
|
||||
public JdbcValuesMappingProducerProvider initiateService(
|
||||
Map<String, Object> configurationValues,
|
||||
ServiceRegistryImplementor registry) {
|
||||
return JdbcValuesMappingProducerProviderStandard.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<JdbcValuesMappingProducerProvider> getServiceInitiated() {
|
||||
return JdbcValuesMappingProducerProvider.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.sql.results.jdbc.internal;
|
||||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.query.results.ResultSetMappingImpl;
|
||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
|
||||
/**
|
||||
* Standard JdbcValuesMappingProducerProvider implementation
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcValuesMappingProducerProviderStandard implements JdbcValuesMappingProducerProvider {
|
||||
/**
|
||||
* Singleton access
|
||||
*/
|
||||
public static final JdbcValuesMappingProducerProviderStandard INSTANCE = new JdbcValuesMappingProducerProviderStandard();
|
||||
|
||||
@Override
|
||||
public JdbcValuesMappingProducer buildMappingProducer(
|
||||
SelectStatement sqlAst,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
return new JdbcValuesMappingProducerStandard(
|
||||
sqlAst.getQuerySpec().getSelectClause().getSqlSelections(),
|
||||
sqlAst.getDomainResultDescriptors()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetMapping buildResultSetMapping(
|
||||
String name,
|
||||
boolean isDynamic,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
return new ResultSetMappingImpl( name, isDynamic );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.sql.results.jdbc.spi;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
|
||||
/**
|
||||
* Pluggable contract for providing custom {@link JdbcValuesMappingProducer} implementations.
|
||||
* This is intended for use by hibernate-reactive to provide its custom implementations.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating
|
||||
public interface JdbcValuesMappingProducerProvider extends Service {
|
||||
/**
|
||||
* Provide the JdbcValuesMappingProducer to use for the given SQL AST
|
||||
*/
|
||||
JdbcValuesMappingProducer buildMappingProducer(SelectStatement sqlAst, SessionFactoryImplementor sessionFactory);
|
||||
|
||||
/**
|
||||
* Provide a dynamically built JdbcValuesMappingProducer
|
||||
*/
|
||||
ResultSetMapping buildResultSetMapping(String name, boolean isDynamic, SessionFactoryImplementor sessionFactory);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.intg.reactive;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.query.results.ResultSetMapping;
|
||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
import org.hibernate.sql.results.jdbc.internal.JdbcValuesMappingProducerProviderStandard;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
|
||||
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.DomainModelScope;
|
||||
import org.hibernate.testing.orm.junit.ExpectedException;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@ServiceRegistry( services = @ServiceRegistry.Service(
|
||||
role = JdbcValuesMappingProducerProvider.class,
|
||||
impl = JdbcValuesMappingProducerProviderTests.CustomJdbcValuesMappingProducerProvider.class
|
||||
) )
|
||||
@DomainModel( annotatedClasses = EntityOfBasics.class )
|
||||
public class JdbcValuesMappingProducerProviderTests {
|
||||
@Test
|
||||
@ExpectedException( GoodIfBadException.class )
|
||||
public void testIt(DomainModelScope scope) {
|
||||
try ( SessionFactory sessionFactory = scope.getDomainModel().buildSessionFactory() ) {
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomJdbcValuesMappingProducerProvider extends JdbcValuesMappingProducerProviderStandard {
|
||||
@Override
|
||||
public JdbcValuesMappingProducer buildMappingProducer(SelectStatement sqlAst, SessionFactoryImplementor sessionFactory) {
|
||||
throw new GoodIfBadException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSetMapping buildResultSetMapping(String name, boolean isDynamic, SessionFactoryImplementor sessionFactory) {
|
||||
throw new GoodIfBadException();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GoodIfBadException extends RuntimeException {
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue