HHH-10664 - Prep 6.0 feature branch - merge hibernate-entitymanager into hibernate-core (fix test failures)

This commit is contained in:
Steve Ebersole 2016-05-02 14:31:39 -05:00
parent 66802a70c1
commit 5a328d1d72
5 changed files with 95 additions and 32 deletions

View File

@ -62,6 +62,7 @@ import org.hibernate.query.ParameterMetadata;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterListBinding;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.type.Type;
@ -293,38 +294,76 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
@Override
@SuppressWarnings("unchecked")
public <P> QueryImplementor setParameter(QueryParameter<P> parameter, P value) {
queryParameterBindings.getBinding( parameter ).setBindValue( value );
locateBinding( parameter ).setBindValue( value );
return this;
}
@SuppressWarnings("unchecked")
private <P> QueryParameterBinding<P> locateBinding(Parameter<P> parameter) {
if ( parameter instanceof QueryParameter ) {
return queryParameterBindings.getBinding( (QueryParameter) parameter );
}
else if ( parameter.getName() != null ) {
return queryParameterBindings.getBinding( parameter.getName() );
}
else if ( parameter.getPosition() != null ) {
return queryParameterBindings.getBinding( parameter.getPosition() );
}
throw getExceptionConverter().convert(
new IllegalArgumentException( "Could not resolve binding for given parameter reference [" + parameter + "]" )
);
}
private <P> QueryParameterBinding<P> locateBinding(QueryParameter<P> parameter) {
return queryParameterBindings.getBinding( parameter );
}
@Override
@SuppressWarnings("unchecked")
public <P> QueryImplementor setParameter(Parameter<P> parameter, P value) {
if ( value instanceof TypedParameterValue ) {
final TypedParameterValue typedValueWrapper = (TypedParameterValue ) value;
setParameter( (QueryParameter) parameter, typedValueWrapper.getValue(), typedValueWrapper.getType() );
setParameter( parameter, ( (TypedParameterValue) value ).getValue(), ( (TypedParameterValue) value ).getType() );
}
else if ( value instanceof Collection ) {
setParameterList( (QueryParameter) parameter, (Collection) value );
}
else if ( parameter instanceof QueryParameter ) {
queryParameterBindings.getBinding( (QueryParameter) parameter ).setBindValue( value );
}
else if ( parameter.getName() != null ) {
queryParameterBindings.getBinding( parameter.getName() ).setBindValue( value );
}
else if ( parameter.getPosition() != null ) {
queryParameterBindings.getBinding( parameter.getPosition() ).setBindValue( value );
locateListBinding( parameter ).setBindValues( (Collection) value );
}
else {
throw getExceptionConverter().convert(
new IllegalArgumentException( "Could not resolve parameter instance [" + parameter + "] as query parameter" )
);
locateBinding( parameter ).setBindValue( value );
}
return this;
}
@SuppressWarnings("unchecked")
private <P> void setParameter(Parameter<P> parameter, Object value, Type type) {
if ( parameter instanceof QueryParameter ) {
setParameter( (QueryParameter) parameter, value, type );
}
else if ( value == null ) {
locateBinding( parameter ).setBindValue( null, type );
}
else if ( value instanceof Collection ) {
locateListBinding( parameter ).setBindValues( (Collection) value, type );
}
else {
locateBinding( parameter ).setBindValue( (P) value, type );
}
}
private QueryParameterListBinding locateListBinding(Parameter parameter) {
if ( parameter instanceof QueryParameter ) {
return queryParameterBindings.getQueryParameterListBinding( (QueryParameter) parameter );
}
else {
return queryParameterBindings.getQueryParameterListBinding( parameter.getName() );
}
}
private QueryParameterListBinding locateListBinding(String name) {
return queryParameterBindings.getQueryParameterListBinding( name );
}
@Override
@SuppressWarnings("unchecked")
public QueryImplementor setParameter(String name, Object value) {
@ -345,7 +384,16 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
@Override
@SuppressWarnings("unchecked")
public QueryImplementor setParameter(int position, Object value) {
queryParameterBindings.getBinding( position ).setBindValue( value );
if ( value instanceof TypedParameterValue ) {
final TypedParameterValue typedParameterValue = (TypedParameterValue) value;
setParameter( position, typedParameterValue.getValue(), typedParameterValue.getType() );
}
if ( value instanceof Collection ) {
setParameterList( Integer.toString( position ), (Collection) value );
}
else {
queryParameterBindings.getBinding( position ).setBindValue( value );
}
return this;
}
@ -494,9 +542,20 @@ public abstract class AbstractProducedQuery<R> implements QueryImplementor<R> {
@Override
public Parameter<?> getParameter(int position) {
// It is important to understand that there are 2 completely distinct conceptualization of
// "positional parameters" in play here:
// 1) The legacy Hibernate concept is akin to JDBC PreparedStatement parameters. Very limited and
// deprecated since 5.x. These are numbered starting from 0 and kept in the
// ParameterMetadata positional-parameter array keyed by this zero-based position
// 2) JPA's definition is really just a named parameter, but expected to explicitly be
// sequential intergers starting from 0 (ZERO); they can repeat.
//
// It is considered illegal to mix positional-parameter with named parameters of any kind. So therefore.
// if ParameterMetadata reports that it has any positional-parameters it is talking about the
// legacy Hibernate concept.
// lookup jpa-based positional parameters first by name.
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
return parameterMetadata.getQueryParameter( String.valueOf( position ) );
return parameterMetadata.getQueryParameter( Integer.toString( position ) );
}
// fallback to oridinal lookup
return parameterMetadata.getQueryParameter( position );

View File

@ -116,13 +116,13 @@ public class ParameterMetadataImpl implements ParameterMetadata {
* @throws QueryParameterException If the position is out of range
*/
public OrdinalParameterDescriptor getOrdinalParameterDescriptor(int position) {
if ( position < 1 || position > ordinalDescriptors.length ) {
if ( position < 0 || position >= ordinalDescriptors.length ) {
throw new QueryParameterException(
"Position beyond number of declared ordinal parameters. " +
"Remember that ordinal parameters are 1-based! Position: " + position
);
}
return ordinalDescriptors[position - 1];
return ordinalDescriptors[position];
}
/**

View File

@ -56,7 +56,9 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T> {
@Override
public void setBindValue(T value, Type clarifiedType) {
setBindValue( value );
this.bindType = clarifiedType;
if ( clarifiedType != null ) {
this.bindType = clarifiedType;
}
}
@Override

View File

@ -199,9 +199,9 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
public QueryParameterBinding getBinding(int position) {
QueryParameterBinding binding = null;
if ( parameterMetadata != null ) {
if ( parameterMetadata.getPositionalParameterCount() == 0 ) {
if ( ! parameterMetadata.hasPositionalParameters() ) {
// no positional parameters, assume jpa named.
binding = locateBinding( String.valueOf( position ) );
binding = locateBinding( Integer.toString( position ) );
}
else {
try {
@ -209,7 +209,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
binding = positionalParameterBindings.get( position );
if ( binding == null ) {
// metadata parameters are 1-based
binding = makeBinding( parameterMetadata.getQueryParameter( position + 1 ) );
binding = makeBinding( parameterMetadata.getQueryParameter( position ) );
positionalParameterBindings.set( position, binding );
}
}
@ -218,7 +218,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
positionalParameterBindings.add( null );
}
// metadata parameters are 1-based
QueryParameter queryParameter = parameterMetadata.getQueryParameter( position + 1 );
QueryParameter queryParameter = parameterMetadata.getQueryParameter( position );
binding = makeBinding( queryParameter );
positionalParameterBindings.add( binding );
}
@ -228,9 +228,11 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {
}
}
}
if ( binding == null ) {
throw new IllegalArgumentException( "Unknown parameter position: " + position );
}
return binding;
}

View File

@ -21,9 +21,7 @@ import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.Tuple;
import junit.framework.Assert;
import org.hibernate.Hibernate;
import org.hibernate.QueryParameterException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQL9Dialect;
@ -34,10 +32,12 @@ import org.hibernate.jpa.test.Distributor;
import org.hibernate.jpa.test.Item;
import org.hibernate.jpa.test.Wallet;
import org.hibernate.stat.Statistics;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.SkipForDialects;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import junit.framework.Assert;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertEquals;
@ -146,7 +146,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
@Override
public Integer getPosition() {
return 1;
return 0;
}
@Override
public Class getParameterType() {
@ -184,7 +184,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
@Override
public Integer getPosition() {
return 1;
return 0;
}
@Override
public Class getParameterType() {
@ -354,7 +354,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
}
@Override
public Integer getPosition() {
return 1;
return 0;
}
@Override
public Class getParameterType() {
@ -846,7 +846,7 @@ public class QueryTest extends BaseEntityManagerFunctionalTestCase {
hqlQuery.setParameter( 2, "Expensive" );
fail( "Should fail due to a user error in parameters" );
}
catch( QueryParameterException e ) {
catch( IllegalArgumentException e ) {
// success expected
e.printStackTrace();
}