parent
5f7c139f7e
commit
bbe3a6b0ad
|
@ -6,24 +6,32 @@
|
|||
*/
|
||||
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.ScrollMode;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.model.domain.AllowableParameterType;
|
||||
import org.hibernate.query.spi.QueryParameterBindings;
|
||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||
import org.hibernate.query.sql.spi.NativeSelectQueryPlan;
|
||||
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.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
||||
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.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.spi.RowTransformer;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -54,8 +62,51 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
|
|||
|
||||
@Override
|
||||
public List<R> performList(ExecutionContext executionContext) {
|
||||
final List<JdbcParameterBinder> jdbcParameterBinders = resolveJdbcParamBinders( executionContext );
|
||||
final JdbcParameterBindings jdbcParameterBindings = resolveJdbcParamBindings( executionContext, jdbcParameterBinders );
|
||||
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() );
|
||||
|
||||
queryParameterBindings.visitBindings(
|
||||
(param, binding) -> {
|
||||
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 JdbcParameterBinding() {
|
||||
@Override
|
||||
public JdbcMapping getBindType() {
|
||||
return jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBindValue() {
|
||||
return binding.getBindValue();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
final JdbcSelect jdbcSelect = new JdbcSelect(
|
||||
sql,
|
||||
|
@ -76,62 +127,53 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
|
|||
);
|
||||
}
|
||||
|
||||
private List<JdbcParameterBinder> resolveJdbcParamBinders(ExecutionContext executionContext) {
|
||||
if ( parameterList == null || parameterList.isEmpty() ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
private JdbcParameterBindings resolveJdbcParamBindings(
|
||||
ExecutionContext executionContext,
|
||||
List<JdbcParameterBinder> jdbcParameterBinders) {
|
||||
if ( jdbcParameterBinders.isEmpty() ) {
|
||||
return JdbcParameterBindings.NO_BINDINGS;
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
// private List<JdbcParameterBinder> resolveJdbcParameterBinders(ExecutionContext executionContext) {
|
||||
// final List<JdbcParameterBinder> jdbcParameterBinders = CollectionHelper.arrayList( parameterList.size() );
|
||||
//
|
||||
// for ( QueryParameterImplementor parameter : parameterList ) {
|
||||
// final QueryParameterBinding parameterBinding = executionContext.getDomainParameterBindingContext()
|
||||
// .getQueryParameterBindings()
|
||||
// .getBinding( parameter );
|
||||
// AllowableParameterType type = parameterBinding.getBindType();
|
||||
// if ( type == null ) {
|
||||
// type = parameter.getHibernateType();
|
||||
// }
|
||||
//
|
||||
// type.dehydrate(
|
||||
// type.unresolve( parameterBinding.getBindValue(), executionContext.getSession() ),
|
||||
// (jdbcValue, sqlExpressableType, boundColumn) -> jdbcParameterBinders.add(
|
||||
// (statement, startPosition, jdbcParameterBindings, executionContext1) -> {
|
||||
// //noinspection unchecked
|
||||
// sqlExpressableType.getJdbcValueBinder().bind(
|
||||
// statement,
|
||||
// startPosition,
|
||||
// jdbcValue,
|
||||
// executionContext1
|
||||
// );
|
||||
// return 1;
|
||||
// }
|
||||
// ),
|
||||
// Clause.IRRELEVANT,
|
||||
// executionContext.getSession()
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// return jdbcParameterBinders;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public ScrollableResultsImplementor<R> performScroll(ScrollMode scrollMode, ExecutionContext executionContext) {
|
||||
final List<JdbcParameterBinder> jdbcParameterBinders = resolveJdbcParamBinders( executionContext );
|
||||
final JdbcParameterBindings jdbcParameterBindings = resolveJdbcParamBindings( executionContext, jdbcParameterBinders );
|
||||
final List<JdbcParameterBinder> jdbcParameterBinders;
|
||||
final JdbcParameterBindings jdbcParameterBindings;
|
||||
|
||||
final QueryParameterBindings queryParameterBindings = executionContext.getQueryParameterBindings();
|
||||
if ( parameterList.isEmpty() ) {
|
||||
jdbcParameterBinders = Collections.emptyList();
|
||||
jdbcParameterBindings = JdbcParameterBindings.NO_BINDINGS;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
|
||||
final JdbcMapping jdbcMapping = ( (BasicValuedMapping) type ).getJdbcMapping();
|
||||
final JdbcParameterImpl jdbcParameter = new JdbcParameterImpl( jdbcMapping );
|
||||
|
||||
jdbcParameterBinders.add( jdbcParameter );
|
||||
|
||||
jdbcParameterBindings.addBinding(
|
||||
jdbcParameter,
|
||||
|
||||
new JdbcParameterBinding() {
|
||||
@Override
|
||||
public JdbcMapping getBindType() {
|
||||
return jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBindValue() {
|
||||
return binding.getBindValue();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
final JdbcSelect jdbcSelect = new JdbcSelect(
|
||||
sql,
|
||||
|
|
|
@ -29,8 +29,6 @@ public class ParameterRecognizerImpl implements ParameterRecognizer {
|
|||
NAMED
|
||||
}
|
||||
|
||||
private final int ordinalParameterBase;
|
||||
|
||||
private ParameterStyle parameterStyle;
|
||||
|
||||
private Map<String, QueryParameterImplementor<?>> namedQueryParameters;
|
||||
|
@ -42,12 +40,6 @@ public class ParameterRecognizerImpl implements ParameterRecognizer {
|
|||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public ParameterRecognizerImpl(SessionFactoryImplementor factory) {
|
||||
if ( factory.getSessionFactoryOptions().isJpaBootstrap() ) {
|
||||
ordinalParameterBase = 1;
|
||||
}
|
||||
else {
|
||||
ordinalParameterBase = 1;
|
||||
}
|
||||
ordinalParameterImplicitPosition = 1;
|
||||
}
|
||||
|
||||
|
@ -63,7 +55,7 @@ public class ParameterRecognizerImpl implements ParameterRecognizer {
|
|||
for ( Integer position : positionsArray ) {
|
||||
if ( position != previous + 1 ) {
|
||||
if ( first ) {
|
||||
throw new QueryException( "Positional parameters did not start with base [" + ordinalParameterBase + "] : " + position );
|
||||
throw new QueryException( "Positional parameters did not start with base 1 : " + position );
|
||||
}
|
||||
else {
|
||||
throw new QueryException( "Gap in positional parameter positions; skipped " + (previous+1) );
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* 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.sql;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||
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.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel( standardModels = StandardDomainModel.HELPDESK )
|
||||
@SessionFactory
|
||||
public class NativeQueryParameterTests {
|
||||
@Test
|
||||
public void testBasicParameterBinding(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createNativeQuery( "select t.id, t.key, t.subject from ticket t where t.key = ?" )
|
||||
.setParameter( 1, "ABC-123" )
|
||||
.list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypedParameterBinding(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createNativeQuery( "select t.id, t.key, t.subject from ticket t where t.key = ?" )
|
||||
.setParameter( 1, "ABC-123", StandardBasicTypes.STRING )
|
||||
.list();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemporalParameterBinding(SessionFactoryScope scope) {
|
||||
final String qryString = "select i.id, i.effectiveStart, i.effectiveEnd " +
|
||||
" from incident i" +
|
||||
" where i.reported BETWEEN ? AND ?";
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
{
|
||||
final Instant now = Instant.now();
|
||||
final Instant startPeriod = now.minus( 30, ChronoUnit.DAYS );
|
||||
|
||||
session.createNativeQuery( qryString )
|
||||
.setParameter( 1, startPeriod )
|
||||
.setParameter( 2, now )
|
||||
.list();
|
||||
}
|
||||
|
||||
{
|
||||
final Instant now = Instant.now();
|
||||
final Instant startPeriod = now.minus( 30, ChronoUnit.DAYS );
|
||||
|
||||
session.createNativeQuery( qryString )
|
||||
.setParameter( 1, startPeriod, TemporalType.DATE )
|
||||
.setParameter( 2, now, TemporalType.DATE )
|
||||
.list();
|
||||
}
|
||||
|
||||
{
|
||||
final Instant now = Instant.now();
|
||||
final Instant startPeriod = now.minus( 30, ChronoUnit.DAYS );
|
||||
|
||||
session.createNativeQuery( qryString )
|
||||
.setParameter( 1, startPeriod, TemporalType.TIMESTAMP )
|
||||
.setParameter( 2, now, TemporalType.TIMESTAMP )
|
||||
.list();
|
||||
}
|
||||
|
||||
{
|
||||
final Instant now = Instant.now();
|
||||
final Instant startPeriod = now.minus( 30, ChronoUnit.DAYS );
|
||||
|
||||
session.createNativeQuery( qryString )
|
||||
.setParameter( 1, startPeriod, TemporalType.TIME )
|
||||
.setParameter( 2, now, TemporalType.TIME )
|
||||
.list();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,8 @@ public class HelpDeskDomainModel extends AbstractDomainModelDescriptor {
|
|||
super(
|
||||
Status.class,
|
||||
Account.class,
|
||||
Ticket.class
|
||||
Ticket.class,
|
||||
Incident.class
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue