Implement non-select native query support and fix parameter binding ordering issues for select native queries
This commit is contained in:
parent
ce41447875
commit
56d90a0aa9
|
@ -179,6 +179,17 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public static void schedule(ExecutionContext executionContext, Set<String> affectedQueryables) {
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, affectedQueryables );
|
||||
if ( session.isEventSource() ) {
|
||||
( (EventSource) session ).getActionQueue().addAction( action );
|
||||
}
|
||||
else {
|
||||
action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether we should consider an entity as affected by the query. This
|
||||
|
|
|
@ -166,7 +166,7 @@ public class DomainResultCreationStateImpl
|
|||
|
||||
@Override
|
||||
public boolean forceIdentifierSelection() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,24 +6,133 @@
|
|||
*/
|
||||
package org.hibernate.query.sql.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.action.internal.BulkOperationCleanupAction;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.MappingModelHelper;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.spi.NonSelectQueryPlan;
|
||||
import org.hibernate.query.spi.QueryParameterBinding;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||
import org.hibernate.query.spi.SqlOmittingQueryOptions;
|
||||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||
import org.hibernate.query.sqm.internal.SqmUtil;
|
||||
import org.hibernate.query.sqm.mutation.internal.SqmMutationStrategyHelper;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.MutatingTableReferenceGroupWrapper;
|
||||
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
|
||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
|
||||
import org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcDelete;
|
||||
import org.hibernate.sql.exec.spi.JdbcMutation;
|
||||
import org.hibernate.sql.exec.spi.JdbcMutationExecutor;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelectExecutor;
|
||||
import org.hibernate.sql.exec.spi.NativeJdbcMutation;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.spi.RowTransformer;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class NativeNonSelectQueryPlanImpl implements NonSelectQueryPlan {
|
||||
private final NativeQueryImplementor nativeQuery;
|
||||
private final String sql;
|
||||
private final Set<String> affectedTableNames;
|
||||
|
||||
public NativeNonSelectQueryPlanImpl(NativeQueryImplementor nativeQuery) {
|
||||
this.nativeQuery = nativeQuery;
|
||||
private final List<QueryParameterImplementor<?>> parameterList;
|
||||
|
||||
public NativeNonSelectQueryPlanImpl(
|
||||
String sql,
|
||||
Set<String> affectedTableNames,
|
||||
List<QueryParameterImplementor<?>> parameterList) {
|
||||
this.sql = sql;
|
||||
this.affectedTableNames = affectedTableNames;
|
||||
this.parameterList = parameterList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(ExecutionContext executionContext) {
|
||||
throw new NotYetImplementedFor6Exception();
|
||||
executionContext.getSession().autoFlushIfRequired( affectedTableNames );
|
||||
BulkOperationCleanupAction.schedule( executionContext, affectedTableNames );
|
||||
final List<JdbcParameterBinder> jdbcParameterBinders;
|
||||
final JdbcParameterBindings jdbcParameterBindings;
|
||||
|
||||
final QueryParameterBindings queryParameterBindings = executionContext.getQueryParameterBindings();
|
||||
if ( parameterList == null || parameterList.isEmpty() ) {
|
||||
jdbcParameterBinders = Collections.emptyList();
|
||||
jdbcParameterBindings = JdbcParameterBindings.NO_BINDINGS;
|
||||
}
|
||||
else {
|
||||
jdbcParameterBinders = new ArrayList<>( parameterList.size() );
|
||||
jdbcParameterBindings = new JdbcParameterBindingsImpl( parameterList.size() );
|
||||
|
||||
for ( QueryParameterImplementor<?> param : parameterList ) {
|
||||
QueryParameterBinding<?> binding = queryParameterBindings.getBinding( param );
|
||||
AllowableParameterType<?> type = binding.getBindType();
|
||||
if ( type == null ) {
|
||||
type = param.getHibernateType();
|
||||
}
|
||||
if ( type == null ) {
|
||||
type = StandardBasicTypes.OBJECT_TYPE;
|
||||
}
|
||||
|
||||
final JdbcMapping jdbcMapping = ( (BasicValuedMapping) type ).getJdbcMapping();
|
||||
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
|
||||
|
||||
jdbcParameterBinders.add( jdbcParameter );
|
||||
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( jdbcMapping, binding.getBindValue() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final JdbcMutation jdbcMutation = new NativeJdbcMutation(
|
||||
sql,
|
||||
jdbcParameterBinders,
|
||||
affectedTableNames
|
||||
);
|
||||
|
||||
final JdbcMutationExecutor executor = StandardJdbcMutationExecutor.INSTANCE;
|
||||
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
// TODO: use configurable executor instead?
|
||||
// final SessionFactoryImplementor factory = session.getFactory();
|
||||
// final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
// return jdbcServices.getJdbcMutationExecutor().execute(
|
||||
return executor.execute(
|
||||
jdbcMutation,
|
||||
jdbcParameterBindings,
|
||||
sql -> session
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql ),
|
||||
(integer, preparedStatement) -> {},
|
||||
executionContext
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,6 +266,7 @@ public class NativeQueryImpl<R>
|
|||
this.parameterMetadata = parameterInterpretation.toParameterMetadata( session );
|
||||
this.occurrenceOrderedParamList = parameterInterpretation.getOccurrenceOrderedParameters();
|
||||
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
|
||||
this.querySpaces = new HashSet<>();
|
||||
|
||||
this.resultSetMapping = new ResultSetMappingImpl( resultSetMappingMemento.getName() );
|
||||
resultSetMappingMemento.resolve(
|
||||
|
@ -301,7 +302,10 @@ public class NativeQueryImpl<R>
|
|||
protected void applyOptions(NamedNativeQueryMemento memento) {
|
||||
super.applyOptions( memento );
|
||||
|
||||
this.querySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
final Set<String> copy = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
if ( copy != null ) {
|
||||
this.querySpaces = copy;
|
||||
}
|
||||
|
||||
// todo (6.0) : query returns
|
||||
}
|
||||
|
@ -579,7 +583,7 @@ public class NativeQueryImpl<R>
|
|||
}
|
||||
|
||||
if ( queryPlan == null ) {
|
||||
queryPlan = new NativeNonSelectQueryPlanImpl( this );
|
||||
queryPlan = new NativeNonSelectQueryPlanImpl( sqlString, querySpaces, occurrenceOrderedParamList );
|
||||
if ( cacheKey != null ) {
|
||||
getSession().getFactory().getQueryEngine().getInterpretationCache().cacheNonSelectQueryPlan( cacheKey, queryPlan );
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.internal.EmptyScrollableResults;
|
|||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
import org.hibernate.query.spi.QueryParameterBinding;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||
|
@ -87,27 +88,26 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
|
|||
jdbcParameterBinders = new ArrayList<>( parameterList.size() );
|
||||
jdbcParameterBindings = new JdbcParameterBindingsImpl( parameterList.size() );
|
||||
|
||||
queryParameterBindings.visitBindings(
|
||||
(param, binding) -> {
|
||||
AllowableParameterType<?> type = binding.getBindType();
|
||||
if ( type == null ) {
|
||||
type = param.getHibernateType();
|
||||
}
|
||||
if ( type == null ) {
|
||||
type = StandardBasicTypes.OBJECT_TYPE;
|
||||
}
|
||||
for ( QueryParameterImplementor<?> param : parameterList ) {
|
||||
QueryParameterBinding<?> binding = queryParameterBindings.getBinding( param );
|
||||
AllowableParameterType<?> type = binding.getBindType();
|
||||
if ( type == null ) {
|
||||
type = param.getHibernateType();
|
||||
}
|
||||
if ( type == null ) {
|
||||
type = StandardBasicTypes.OBJECT_TYPE;
|
||||
}
|
||||
|
||||
final JdbcMapping jdbcMapping = ( (BasicValuedMapping) type ).getJdbcMapping();
|
||||
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
|
||||
final JdbcMapping jdbcMapping = ( (BasicValuedMapping) type ).getJdbcMapping();
|
||||
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
|
||||
|
||||
jdbcParameterBinders.add( jdbcParameter );
|
||||
jdbcParameterBinders.add( jdbcParameter );
|
||||
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( jdbcMapping, binding.getBindValue() )
|
||||
);
|
||||
}
|
||||
);
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
new JdbcParameterBindingImpl( jdbcMapping, binding.getBindValue() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
executionContext.getSession().autoFlushIfRequired( affectedTableNames );
|
||||
|
@ -122,6 +122,11 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
|
|||
|
||||
final JdbcSelectExecutor executor = JdbcSelectExecutorStandardImpl.INSTANCE;
|
||||
|
||||
// TODO: use configurable executor instead?
|
||||
// final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
// final SessionFactoryImplementor factory = session.getFactory();
|
||||
// final JdbcServices jdbcServices = factory.getJdbcServices();
|
||||
// return jdbcServices.getJdbcMutationExecutor().execute(
|
||||
return executor.list(
|
||||
jdbcSelect,
|
||||
jdbcParameterBindings,
|
||||
|
|
|
@ -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.sql.exec.spi;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.internal.FilterJdbcParameter;
|
||||
|
||||
/**
|
||||
* Executable JDBC command
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class NativeJdbcMutation implements JdbcMutation {
|
||||
private final String sql;
|
||||
private final List<JdbcParameterBinder> parameterBinders;
|
||||
private final Set<String> affectedTableNames;
|
||||
|
||||
public NativeJdbcMutation(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames) {
|
||||
this.sql = sql;
|
||||
this.parameterBinders = parameterBinders;
|
||||
this.affectedTableNames = affectedTableNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JdbcParameterBinder> getParameterBinders() {
|
||||
return parameterBinders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAffectedTableNames() {
|
||||
return affectedTableNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue