HHH-16226 - Introduce JdbcValuesMappingProducerProvider

This commit is contained in:
Steve Ebersole 2023-02-23 17:33:34 -06:00
parent 88ed4fdb91
commit a36f6aa736
12 changed files with 288 additions and 36 deletions

View File

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

View File

@ -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,

View File

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

View File

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

View File

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

View File

@ -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() ) ) {

View File

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

View File

@ -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() ) {

View File

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

View File

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

View File

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

View File

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