HHH-8419 - Tie javax.persistence.Parameter instance to javax.persistence.Query instance
This commit is contained in:
parent
742b1b4156
commit
3d595febc5
|
@ -61,6 +61,8 @@ import org.hibernate.jpa.internal.util.ConfigurationHelper;
|
|||
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
|
||||
import org.hibernate.jpa.spi.AbstractEntityManagerImpl;
|
||||
import org.hibernate.jpa.spi.AbstractQueryImpl;
|
||||
import org.hibernate.jpa.spi.ParameterBind;
|
||||
import org.hibernate.jpa.spi.ParameterRegistration;
|
||||
import org.hibernate.type.CompositeCustomType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -112,7 +114,7 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
else if ( descriptor.getExpectedType() != null ) {
|
||||
javaType = descriptor.getExpectedType().getReturnedClass();
|
||||
}
|
||||
registerParameter( new ParameterRegistrationImpl( query, name, javaType ) );
|
||||
registerParameter( new ParameterRegistrationImpl( this, query, name, javaType ) );
|
||||
if ( descriptor.isJpaStyle() ) {
|
||||
if ( jpaPositionalIndices == null ) {
|
||||
jpaPositionalIndices = new HashSet<Integer>();
|
||||
|
@ -125,7 +127,7 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
for ( int i = 0, max = parameterMetadata.getOrdinalParameterCount(); i < max; i++ ) {
|
||||
final OrdinalParameterDescriptor descriptor = parameterMetadata.getOrdinalParameterDescriptor( i + 1 );
|
||||
Class javaType = descriptor.getExpectedType() == null ? null : descriptor.getExpectedType().getReturnedClass();
|
||||
registerParameter( new ParameterRegistrationImpl( query, i+1, javaType ) );
|
||||
registerParameter( new ParameterRegistrationImpl( this, query, i+1, javaType ) );
|
||||
Integer position = descriptor.getOrdinalPosition();
|
||||
if ( jpaPositionalIndices != null && jpaPositionalIndices.contains(position) ) {
|
||||
LOG.parameterPositionOccurredAsBothJpaAndHibernatePositionalParameter(position);
|
||||
|
@ -147,7 +149,8 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
}
|
||||
|
||||
private static class ParameterRegistrationImpl<T> implements ParameterRegistration<T> {
|
||||
private final org.hibernate.Query query;
|
||||
private final Query jpaQuery;
|
||||
private final org.hibernate.Query nativeQuery;
|
||||
|
||||
private final String name;
|
||||
private final Integer position;
|
||||
|
@ -155,20 +158,35 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
|
||||
private ParameterBind<T> bind;
|
||||
|
||||
private ParameterRegistrationImpl(org.hibernate.Query query, String name, Class<T> javaType) {
|
||||
this.query = query;
|
||||
private ParameterRegistrationImpl(
|
||||
Query jpaQuery,
|
||||
org.hibernate.Query nativeQuery,
|
||||
String name,
|
||||
Class<T> javaType) {
|
||||
this.jpaQuery = jpaQuery;
|
||||
this.nativeQuery = nativeQuery;
|
||||
this.name = name;
|
||||
this.javaType = javaType;
|
||||
this.position = null;
|
||||
}
|
||||
|
||||
private ParameterRegistrationImpl(org.hibernate.Query query, Integer position, Class<T> javaType) {
|
||||
this.query = query;
|
||||
private ParameterRegistrationImpl(
|
||||
Query jpaQuery,
|
||||
org.hibernate.Query nativeQuery,
|
||||
Integer position,
|
||||
Class<T> javaType) {
|
||||
this.jpaQuery = jpaQuery;
|
||||
this.nativeQuery = nativeQuery;
|
||||
this.position = position;
|
||||
this.javaType = javaType;
|
||||
this.name = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query getQuery() {
|
||||
return jpaQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
@ -202,14 +220,14 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
|
||||
if ( name != null ) {
|
||||
if ( value instanceof Collection ) {
|
||||
query.setParameterList( name, (Collection) value );
|
||||
nativeQuery.setParameterList( name, (Collection) value );
|
||||
}
|
||||
else {
|
||||
query.setParameter( name, value );
|
||||
nativeQuery.setParameter( name, value );
|
||||
}
|
||||
}
|
||||
else {
|
||||
query.setParameter( position-1, value );
|
||||
nativeQuery.setParameter( position - 1, value );
|
||||
}
|
||||
|
||||
bind = new ParameterBindImpl<T>( value, null );
|
||||
|
@ -222,48 +240,48 @@ public class QueryImpl<X> extends AbstractQueryImpl<X> implements TypedQuery<X>,
|
|||
if ( Date.class.isInstance( value ) ) {
|
||||
if ( name != null ) {
|
||||
if ( specifiedTemporalType == DATE ) {
|
||||
query.setDate( name, (Date) value );
|
||||
nativeQuery.setDate( name, (Date) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIME ) {
|
||||
query.setTime( name, (Date) value );
|
||||
nativeQuery.setTime( name, (Date) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIMESTAMP ) {
|
||||
query.setTimestamp( name, (Date) value );
|
||||
nativeQuery.setTimestamp( name, (Date) value );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( specifiedTemporalType == DATE ) {
|
||||
query.setDate( position-1, (Date) value );
|
||||
nativeQuery.setDate( position - 1, (Date) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIME ) {
|
||||
query.setTime( position-1, (Date) value );
|
||||
nativeQuery.setTime( position - 1, (Date) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIMESTAMP ) {
|
||||
query.setTimestamp( position-1, (Date) value );
|
||||
nativeQuery.setTimestamp( position - 1, (Date) value );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( Calendar.class.isInstance( value ) ) {
|
||||
if ( name != null ) {
|
||||
if ( specifiedTemporalType == DATE ) {
|
||||
query.setCalendarDate( name, (Calendar) value );
|
||||
nativeQuery.setCalendarDate( name, (Calendar) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIME ) {
|
||||
throw new IllegalArgumentException( "not yet implemented" );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIMESTAMP ) {
|
||||
query.setCalendar( name, (Calendar) value );
|
||||
nativeQuery.setCalendar( name, (Calendar) value );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( specifiedTemporalType == DATE ) {
|
||||
query.setCalendarDate( position-1, (Calendar) value );
|
||||
nativeQuery.setCalendarDate( position - 1, (Calendar) value );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIME ) {
|
||||
throw new IllegalArgumentException( "not yet implemented" );
|
||||
}
|
||||
else if ( specifiedTemporalType == TIMESTAMP ) {
|
||||
query.setCalendar( position-1, (Calendar) value );
|
||||
nativeQuery.setCalendar( position - 1, (Calendar) value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ import java.util.List;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.jpa.spi.ParameterBind;
|
||||
import org.hibernate.jpa.spi.ParameterRegistration;
|
||||
import org.hibernate.procedure.NoSuchParameterException;
|
||||
import org.hibernate.procedure.ParameterStrategyException;
|
||||
import org.hibernate.procedure.ProcedureCall;
|
||||
|
@ -76,7 +78,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
super( entityManager );
|
||||
this.procedureCall = memento.makeProcedureCall( entityManager.getSession() );
|
||||
for ( org.hibernate.procedure.ParameterRegistration nativeParamReg : procedureCall.getRegisteredParameters() ) {
|
||||
registerParameter( new ParameterRegistrationImpl( nativeParamReg ) );
|
||||
registerParameter( new ParameterRegistrationImpl( this, nativeParamReg ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +124,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
entityManager().checkOpen( true );
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( position, type, mode )
|
||||
)
|
||||
);
|
||||
|
@ -134,6 +137,7 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
entityManager().checkOpen( true );
|
||||
registerParameter(
|
||||
new ParameterRegistrationImpl(
|
||||
this,
|
||||
procedureCall.registerParameter( parameterName, type, mode )
|
||||
)
|
||||
);
|
||||
|
@ -407,11 +411,15 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
}
|
||||
|
||||
private static class ParameterRegistrationImpl<T> implements ParameterRegistration<T> {
|
||||
private final StoredProcedureQueryImpl query;
|
||||
private final org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration;
|
||||
|
||||
private ParameterBind<T> bind;
|
||||
|
||||
private ParameterRegistrationImpl(org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration) {
|
||||
public ParameterRegistrationImpl(
|
||||
StoredProcedureQueryImpl query,
|
||||
org.hibernate.procedure.ParameterRegistration<T> nativeParamRegistration) {
|
||||
this.query = query;
|
||||
this.nativeParamRegistration = nativeParamRegistration;
|
||||
}
|
||||
|
||||
|
@ -430,6 +438,11 @@ public class StoredProcedureQueryImpl extends BaseQueryImpl implements StoredPro
|
|||
return nativeParamRegistration.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParameterMode getMode() {
|
||||
return nativeParamRegistration.getMode();
|
||||
|
|
|
@ -27,7 +27,6 @@ import javax.persistence.CacheRetrieveMode;
|
|||
import javax.persistence.CacheStoreMode;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Calendar;
|
||||
|
@ -409,7 +408,12 @@ public abstract class BaseQueryImpl implements Query {
|
|||
|
||||
protected <X> ParameterRegistration<X> findParameterRegistration(Parameter<X> parameter) {
|
||||
if ( ParameterRegistration.class.isInstance( parameter ) ) {
|
||||
return (ParameterRegistration<X>) parameter;
|
||||
final ParameterRegistration<X> reg = (ParameterRegistration<X>) parameter;
|
||||
// validate the parameter source
|
||||
if ( reg.getQuery() != this ) {
|
||||
throw new IllegalArgumentException( "Passed Parameter was from different Query" );
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
else {
|
||||
if ( parameter.getName() != null ) {
|
||||
|
@ -440,45 +444,6 @@ public abstract class BaseQueryImpl implements Query {
|
|||
|
||||
protected abstract boolean isJpaPositionalParameter(int position);
|
||||
|
||||
/**
|
||||
* Hibernate specific extension to the JPA {@link javax.persistence.Parameter} contract. Used here to track
|
||||
* information known about the parameter.
|
||||
*/
|
||||
protected static interface ParameterRegistration<T> extends Parameter<T> {
|
||||
/**
|
||||
* Retrieves the parameter "mode" which describes how the parameter is defined in the actual database procedure
|
||||
* definition (is it an INPUT parameter? An OUTPUT parameter? etc).
|
||||
*
|
||||
* @return The parameter mode.
|
||||
*/
|
||||
public ParameterMode getMode();
|
||||
|
||||
/**
|
||||
* Can we bind (set) values on this parameter? Generally this is {@code true}, but would not be in the case
|
||||
* of parameters with OUT or REF_CURSOR mode.
|
||||
*
|
||||
* @return Whether the parameter is bindable (can set be called).
|
||||
*/
|
||||
public boolean isBindable();
|
||||
|
||||
public void bindValue(T value);
|
||||
|
||||
public void bindValue(T value, TemporalType specifiedTemporalType);
|
||||
|
||||
public ParameterBind<T> getBind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the value currently bound to a particular parameter.
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
protected static interface ParameterBind<T> {
|
||||
public T getValue();
|
||||
|
||||
public TemporalType getSpecifiedTemporalType();
|
||||
}
|
||||
|
||||
protected static class ParameterBindImpl<T> implements ParameterBind<T> {
|
||||
private final T value;
|
||||
private final TemporalType specifiedTemporalType;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.spi;
|
||||
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
* Represents the value currently bound to a particular (bindable) parameter.
|
||||
*
|
||||
* @param <T>
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ParameterBind<T> {
|
||||
/**
|
||||
* Access the bound value
|
||||
*
|
||||
* @return The bound value
|
||||
*/
|
||||
public T getValue();
|
||||
|
||||
/**
|
||||
* The temporal type that will be used to "interpret" Date-like values (if applicable).
|
||||
*
|
||||
* @return The temporal type, or {@code null}
|
||||
*/
|
||||
public TemporalType getSpecifiedTemporalType();
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.jpa.spi;
|
||||
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.ParameterMode;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
* Hibernate specific extension to the JPA {@link javax.persistence.Parameter} contract as known to the
|
||||
* {@link javax.persistence.Query} and {@link javax.persistence.StoredProcedureQuery} implementations. Used to track
|
||||
* information known about the parameter.
|
||||
* <p/>
|
||||
* For parameter information as known to JPA criteria queries, see {@link org.hibernate.jpa.criteria.expression.ParameterExpressionImpl}
|
||||
* instead.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ParameterRegistration<T> extends Parameter<T> {
|
||||
/**
|
||||
* Access to the query that this parameter belongs to.
|
||||
*
|
||||
* @return The defining query
|
||||
*/
|
||||
public Query getQuery();
|
||||
|
||||
/**
|
||||
* Retrieves the parameter "mode" which describes how the parameter is defined in the actual database procedure
|
||||
* definition (is it an INPUT parameter? An OUTPUT parameter? etc).
|
||||
*
|
||||
* @return The parameter mode.
|
||||
*/
|
||||
public ParameterMode getMode();
|
||||
|
||||
/**
|
||||
* Can we bind (set) values on this parameter? Generally this is {@code true}, but would not be in the case
|
||||
* of parameters with OUT or REF_CURSOR mode.
|
||||
*
|
||||
* @return Whether the parameter is bindable (can set be called).
|
||||
*/
|
||||
public boolean isBindable();
|
||||
|
||||
/**
|
||||
* If bindable, bind the value.
|
||||
*
|
||||
* @param value The value to bind.
|
||||
*/
|
||||
public void bindValue(T value);
|
||||
|
||||
/**
|
||||
* If bindable, bind the value using the specific temporal type.
|
||||
*
|
||||
* @param value The value to bind
|
||||
* @param specifiedTemporalType The temporal type to use in binding
|
||||
*/
|
||||
public void bindValue(T value, TemporalType specifiedTemporalType);
|
||||
|
||||
/**
|
||||
* If bindable, get the current binding.
|
||||
*
|
||||
* @return The current binding
|
||||
*/
|
||||
public ParameterBind<T> getBind();
|
||||
}
|
Loading…
Reference in New Issue