Skip to content

Commit 096916e

Browse files
committed
HHH-13310 getParameterValue() not working for collections
1 parent 36f9360 commit 096916e

File tree

3 files changed

+101
-33
lines changed

3 files changed

+101
-33
lines changed

hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java

+85-33
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
import java.util.Set;
2626
import java.util.Spliterator;
2727
import java.util.Spliterators;
28+
import java.util.function.BiConsumer;
29+
import java.util.function.BiFunction;
30+
import java.util.function.Consumer;
31+
import java.util.function.Function;
32+
import java.util.function.Supplier;
2833
import java.util.stream.Stream;
2934
import java.util.stream.StreamSupport;
3035
import javax.persistence.CacheRetrieveMode;
@@ -752,57 +757,104 @@ public boolean isBound(Parameter<?> parameter) {
752757
@Override
753758
public <T> T getParameterValue(Parameter<T> parameter) {
754759
LOGGER.tracef( "#getParameterValue(%s)", parameter );
755-
756760
getProducer().checkOpen( false );
757761

758-
if ( !getParameterMetadata().containsReference( (QueryParameter) parameter ) ) {
759-
throw new IllegalArgumentException( "Parameter reference [" + parameter + "] did not come from this query" );
760-
}
761-
762-
final QueryParameterBinding<T> binding = getQueryParameterBindings().getBinding( (QueryParameter<T>) parameter );
763-
LOGGER.debugf( "Checking whether parameter reference [%s] is bound : %s", parameter, binding.isBound() );
764-
if ( !binding.isBound() ) {
765-
throw new IllegalStateException( "Parameter value not yet bound : " + parameter.toString() );
766-
}
767-
return binding.getBindValue();
762+
return (T) getParameterValue(
763+
(QueryParameter) parameter,
764+
(queryParameter) -> new IllegalStateException( "Parameter value not yet bound : " + queryParameter.toString() ),
765+
(queryParameter, e) -> {
766+
final String message = "Parameter reference [" + queryParameter + "] did not come from this query";
767+
if ( e == null ) {
768+
return new IllegalArgumentException( message );
769+
}
770+
return new IllegalArgumentException( message, e );
771+
},
772+
(queryParameter, isBound) -> LOGGER.debugf(
773+
"Checking whether parameter reference [%s] is bound : %s",
774+
queryParameter,
775+
isBound
776+
)
777+
);
768778
}
769779

770780
@Override
771781
public Object getParameterValue(String name) {
772782
getProducer().checkOpen( false );
773783

774-
final QueryParameterBinding binding;
775-
try {
776-
binding = getQueryParameterBindings().getBinding( name );
777-
}
778-
catch (QueryParameterException e) {
779-
throw new IllegalArgumentException( "Could not resolve parameter by name - " + name, e );
780-
}
781-
782-
LOGGER.debugf( "Checking whether named parameter [%s] is bound : %s", name, binding.isBound() );
783-
if ( !binding.isBound() ) {
784-
throw new IllegalStateException( "Parameter value not yet bound : " + name );
785-
}
786-
return binding.getBindValue();
784+
final QueryParameter<Object> queryParameter = getParameterMetadata().getQueryParameter( name );
785+
return getParameterValue(
786+
queryParameter,
787+
(parameter) -> new IllegalStateException( "Parameter value not yet bound : " + parameter.getName() ),
788+
(parameter, e) -> {
789+
final String message = "Could not resolve parameter by name - " + parameter.getName();
790+
if ( e == null ) {
791+
return new IllegalArgumentException( message );
792+
}
793+
return new IllegalArgumentException( message, e );
794+
},
795+
(parameter, isBound) -> LOGGER.debugf(
796+
"Checking whether positional named [%s] is bound : %s",
797+
parameter.getName(),
798+
isBound
799+
)
800+
);
787801
}
788802

789803
@Override
790804
public Object getParameterValue(int position) {
791805
getProducer().checkOpen( false );
792806

793-
final QueryParameterBinding binding;
807+
final QueryParameter<Object> queryParameter = getParameterMetadata().getQueryParameter( position );
808+
return getParameterValue(
809+
queryParameter,
810+
(parameter) -> new IllegalStateException( "Parameter value not yet bound : " + parameter.getPosition() ),
811+
(parameter, e) -> {
812+
String message = "Could not resolve parameter by position - " + parameter.getPosition();
813+
if ( e == null ) {
814+
return new IllegalArgumentException( message );
815+
}
816+
return new IllegalArgumentException( message, e );
817+
},
818+
(parameter, isBound) -> LOGGER.debugf(
819+
"Checking whether positional parameter [%s] is bound : %s",
820+
parameter.getPosition(),
821+
isBound
822+
)
823+
);
824+
}
825+
826+
private Object getParameterValue(
827+
QueryParameter queryParameter,
828+
Function<QueryParameter, IllegalStateException> notBoundParamenterException,
829+
BiFunction<QueryParameter, QueryParameterException, IllegalArgumentException> couldNotResolveParameterException,
830+
BiConsumer<QueryParameter, Boolean> boundCheckingLogger) {
794831
try {
795-
binding = getQueryParameterBindings().getBinding( position );
832+
final QueryParameterBindings parameterBindings = getQueryParameterBindings();
833+
834+
if ( queryParameter == null ) {
835+
throw couldNotResolveParameterException.apply( queryParameter, null );
836+
}
837+
if ( parameterBindings.isMultiValuedBinding( queryParameter ) ) {
838+
final QueryParameterListBinding<Object> queryParameterListBinding = parameterBindings
839+
.getQueryParameterListBinding( queryParameter );
840+
final Collection<Object> bindValues = queryParameterListBinding.getBindValues();
841+
if ( bindValues == null ) {
842+
throw notBoundParamenterException.apply( queryParameter );
843+
}
844+
return bindValues;
845+
}
846+
847+
final QueryParameterBinding<Object> binding = parameterBindings.getBinding( queryParameter );
848+
final boolean bound = binding.isBound();
849+
boundCheckingLogger.accept( queryParameter, bound );
850+
if ( !bound ) {
851+
throw notBoundParamenterException.apply( queryParameter );
852+
}
853+
return binding.getBindValue();
796854
}
797855
catch (QueryParameterException e) {
798-
throw new IllegalArgumentException( "Could not resolve parameter by position - " + position, e );
799-
}
800-
801-
LOGGER.debugf( "Checking whether positional parameter [%s] is bound : %s", (Integer) position, (Boolean) binding.isBound() );
802-
if ( !binding.isBound() ) {
803-
throw new IllegalStateException( "Parameter value not yet bound : " + position );
856+
throw couldNotResolveParameterException.apply( queryParameter, e );
804857
}
805-
return binding.getBindValue();
806858
}
807859

808860
@Override

hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java

+8
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,14 @@ public Object[] collectPositionalBindValues() {
317317
// return values.toArray( new Object[values.size()] );
318318
}
319319

320+
@Override
321+
public boolean isMultiValuedBinding(QueryParameter parameter) {
322+
if ( parameterListBindingMap == null ) {
323+
return false;
324+
}
325+
return parameterListBindingMap.containsKey( parameter );
326+
}
327+
320328
/**
321329
* @deprecated (since 5.2) expect a different approach to org.hibernate.engine.spi.QueryParameters in 6.0
322330
*/

hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindings.java

+8
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,12 @@ public interface QueryParameterBindings {
3535
Type[] collectPositionalBindTypes();
3636
Object[] collectPositionalBindValues();
3737
Map<String,TypedValue> collectNamedParameterBindings();
38+
39+
/**
40+
* @deprecated expect a different approach to org.hibernate.engine.spi.QueryParameters in 6.0
41+
*/
42+
@Deprecated
43+
default boolean isMultiValuedBinding(QueryParameter parameter) {
44+
return false;
45+
}
3846
}

0 commit comments

Comments
 (0)