4343import org .hibernate .query .sqm .tree .select .SqmSelectStatement ;
4444import org .hibernate .type .BindableType ;
4545import org .hibernate .type .descriptor .java .JavaType ;
46+ import org .hibernate .type .descriptor .java .TemporalJavaType ;
4647import org .hibernate .type .spi .TypeConfiguration ;
4748
4849import java .time .Instant ;
@@ -702,9 +703,11 @@ private <P> JavaType<P> getJavaType(Class<P> javaType) {
702703.resolveDescriptor ( javaType );
703704}
704705
705- protected <P > QueryParameterBinding <P > locateBinding (Parameter <P > parameter , P value ) {
706+ protected <P > QueryParameterBinding <P > locateBinding (Parameter <P > parameter , Object value ) {
706707if ( parameter instanceof QueryParameterImplementor <P > parameterImplementor ) {
707- return locateBinding ( parameterImplementor );
708+ getCheckOpen ();
709+ return getQueryParameterBindings ()
710+ .getBinding ( getQueryParameter ( parameterImplementor ) );
708711}
709712else {
710713final String name = parameter .getName ();
@@ -723,43 +726,17 @@ else if ( position != null ) {
723726);
724727}
725728
726- protected <P > QueryParameterBinding <P > locateBinding (Parameter <P > parameter , Collection <? extends P > values ) {
727- if ( parameter instanceof QueryParameterImplementor <P > parameterImplementor ) {
728- return locateBinding ( parameterImplementor );
729- }
730- else {
731- final String name = parameter .getName ();
732- final Integer position = parameter .getPosition ();
733- final var parameterType = parameter .getParameterType ();
734- if ( name != null ) {
735- return locateBinding ( name , parameterType , values );
736- }
737- else if ( position != null ) {
738- return locateBinding ( position , parameterType , values );
739- }
740- }
741-
742- throw getExceptionConverter ().convert (
743- new IllegalArgumentException ( "Could not resolve binding for given parameter reference [" + parameter + "]" )
744- );
745- }
746-
747- protected <P > QueryParameterBinding <P > locateBinding (QueryParameterImplementor <P > parameter ) {
748- getCheckOpen ();
749- return getQueryParameterBindings ()
750- .getBinding ( getQueryParameter ( parameter ) );
751- }
752-
753- protected <P > QueryParameterBinding <P > locateBinding (String name , Class <P > javaType , P value ) {
729+ protected <P > QueryParameterBinding <P > locateBinding (String name , Class <P > javaType , Object value ) {
754730getCheckOpen ();
755731final var binding = getQueryParameterBindings ().getBinding ( name );
756732final var parameterType = binding .getBindType ();
757- if ( parameterType != null ) {
733+ if ( parameterType != null && value != null ) {
758734final var parameterJavaType = parameterType .getJavaType ();
759735if ( !parameterJavaType .isAssignableFrom ( javaType )
760- && !isInstance ( parameterType , value , getNodeBuilder () ) ) {
736+ && !( java .util .Date .class .isAssignableFrom ( parameterJavaType )
737+ && javaType == java .sql .Timestamp .class ) ) {
761738throw new QueryArgumentException (
762- "Argument to parameter named '" + name + "' has an incompatible type" ,
739+ "Parameter named '" + name + "' has an incompatible type" ,
763740parameterJavaType , javaType , value );
764741}
765742}
@@ -768,58 +745,72 @@ protected <P> QueryParameterBinding<P> locateBinding(String name, Class<P> javaT
768745return castBinding ;
769746}
770747
771- protected < P > QueryParameterBinding <P > locateBinding (int position , Class < P > javaType , P value ) {
748+ protected QueryParameterBinding <? > locateBinding (String name , TemporalType temporalType , Object value ) {
772749getCheckOpen ();
773- final var binding = getQueryParameterBindings ().getBinding ( position );
750+ final var binding = getQueryParameterBindings ().getBinding ( name );
774751final var parameterType = binding .getBindType ();
775- if ( parameterType != null ) {
776- final var parameterJavaType = parameterType .getJavaType ();
777- if ( !parameterJavaType .isAssignableFrom ( javaType )
778- && !isInstance ( parameterType , value , getNodeBuilder () ) ) {
779- throw new QueryArgumentException (
780- "Argument to parameter at position " + position + " has an incompatible type" ,
781- parameterJavaType , javaType , value );
782- }
752+ if ( parameterType != null && value != null
753+ && !isCompatibleTemporal ( temporalType , parameterType ) ) {
754+ throw new QueryArgumentException (
755+ "Parameter named '" + name + "' has an incompatible type" ,
756+ parameterType .getJavaType (), temporalJavaType ( temporalType ), value );
783757}
784- @ SuppressWarnings ("unchecked" ) // safe, just checked
785- var castBinding = (QueryParameterBinding <P >) binding ;
786- return castBinding ;
758+ return binding ;
787759}
788760
789- protected <P > QueryParameterBinding <P > locateBinding (String name , Class <P > javaType , Collection <? extends P > values ) {
761+ protected <P > QueryParameterBinding <P > locateBinding (int position , Class <P > javaType , Object value ) {
790762getCheckOpen ();
791- final var binding = getQueryParameterBindings ().getBinding ( name );
763+ final var binding = getQueryParameterBindings ().getBinding ( position );
792764final var parameterType = binding .getBindType ();
793- if ( parameterType != null ) {
765+ if ( parameterType != null && value != null ) {
794766final var parameterJavaType = parameterType .getJavaType ();
795- if ( !parameterJavaType .isAssignableFrom ( javaType )
796- && !areInstances ( parameterType , values , getNodeBuilder () ) ) {
767+ if ( !parameterJavaType .isAssignableFrom ( javaType ) ) {
797768throw new QueryArgumentException (
798- "Argument to parameter named ' " + name + "' has an incompatible type" ,
799- parameterJavaType , javaType , values );
769+ "Parameter at position " + position + " has an incompatible type" ,
770+ parameterJavaType , javaType , value );
800771}
801772}
802773@ SuppressWarnings ("unchecked" ) // safe, just checked
803774var castBinding = (QueryParameterBinding <P >) binding ;
804775return castBinding ;
805776}
806777
807- protected < P > QueryParameterBinding <P > locateBinding (int position , Class < P > javaType , Collection <? extends P > values ) {
778+ protected QueryParameterBinding <? > locateBinding (int position , TemporalType temporalType , Object value ) {
808779getCheckOpen ();
809780final var binding = getQueryParameterBindings ().getBinding ( position );
810781final var parameterType = binding .getBindType ();
811- if ( parameterType != null ) {
812- final var parameterJavaType = parameterType .getJavaType ();
813- if ( !parameterJavaType .isAssignableFrom ( javaType )
814- && !areInstances ( parameterType , values , getNodeBuilder () ) ) {
815- throw new QueryArgumentException (
816- "Argument to parameter at position " + position + " has an incompatible type" ,
817- parameterJavaType , javaType , values );
818- }
782+ if ( parameterType != null && value != null
783+ && !isCompatibleTemporal ( temporalType , parameterType ) ) {
784+ throw new QueryArgumentException (
785+ "Parameter at position '" + position + "' has an incompatible type" ,
786+ parameterType .getJavaType (), temporalJavaType ( temporalType ), value );
819787}
820- @ SuppressWarnings ("unchecked" ) // safe, just checked
821- var castBinding = (QueryParameterBinding <P >) binding ;
822- return castBinding ;
788+ return binding ;
789+ }
790+
791+ @ SuppressWarnings ("deprecation" )
792+ private boolean isCompatibleTemporal (TemporalType temporalType , BindableType <?> parameterType ) {
793+ if ( parameterType .resolveExpressible ( getNodeBuilder () ).getExpressibleJavaType ()
794+ instanceof TemporalJavaType <?> temporalJavaType ) {
795+ return switch ( temporalJavaType .getPrecision () ) {
796+ // we have tests that assert I can compare anything with a timestamp
797+ case TIMESTAMP -> true ; // temporalType == TemporalType.TIMESTAMP;
798+ case DATE -> temporalType != TemporalType .TIME ;
799+ case TIME -> temporalType != TemporalType .DATE ;
800+ };
801+ }
802+ else {
803+ return false ;
804+ }
805+ }
806+
807+ private static Class <?> temporalJavaType (
808+ @ SuppressWarnings ("deprecation" ) TemporalType temporalType ) {
809+ return switch ( temporalType ) {
810+ case DATE -> java .sql .Date .class ;
811+ case TIME -> java .sql .Time .class ;
812+ case TIMESTAMP -> java .sql .Timestamp .class ;
813+ };
823814}
824815
825816protected <P > QueryParameterImplementor <P > getQueryParameter (QueryParameterImplementor <P > parameter ) {
@@ -958,7 +949,7 @@ public <P> CommonQueryContract setParameter(String name, P value, Type<P> type)
958949
959950@ Override @ Deprecated (since = "7" )
960951public CommonQueryContract setParameter (String name , Instant value , TemporalType temporalType ) {
961- locateBinding ( name , Instant . class , value ).setBindValue ( value , temporalType );
952+ locateBinding ( name , temporalType , value ).setBindValue ( value , temporalType );
962953return this ;
963954}
964955
@@ -1004,14 +995,13 @@ public <P> CommonQueryContract setParameter(int position, P value, Type<P> type)
1004995
1005996@ Override @ Deprecated (since = "7" )
1006997public CommonQueryContract setParameter (int position , Instant value , TemporalType temporalType ) {
1007- locateBinding ( position , Instant . class , value ).setBindValue ( value , temporalType );
998+ locateBinding ( position , temporalType , value ).setBindValue ( value , temporalType );
1008999return this ;
10091000}
10101001
10111002@ Override
10121003public <P > CommonQueryContract setParameter (QueryParameter <P > parameter , P value ) {
1013- locateBinding ( parameter , value )
1014- .setBindValue ( value , resolveJdbcParameterTypeIfNecessary () );
1004+ locateBinding ( parameter , value ).setBindValue ( value , resolveJdbcParameterTypeIfNecessary () );
10151005return this ;
10161006}
10171007
@@ -1029,8 +1019,7 @@ public <P> CommonQueryContract setParameter(QueryParameter<P> parameter, P value
10291019
10301020@ Override
10311021public <P > CommonQueryContract setParameter (QueryParameter <P > parameter , P value , Type <P > type ) {
1032- locateBinding ( parameter , value )
1033- .setBindValue ( value , (BindableType <P >) type );
1022+ locateBinding ( parameter , value ).setBindValue ( value , (BindableType <P >) type );
10341023return this ;
10351024}
10361025
@@ -1074,31 +1063,31 @@ public CommonQueryContract setParameter(Parameter<Calendar> param, Calendar valu
10741063
10751064@ Override @ Deprecated
10761065public CommonQueryContract setParameter (Parameter <Date > param , Date value , TemporalType temporalType ) {
1077- locateBinding ( param , value ).setBindValue ( value , temporalType );
1066+ locateBinding ( param . getName (), temporalType , value ).setBindValue ( value , temporalType );
10781067return this ;
10791068}
10801069
10811070@ Override @ Deprecated
10821071public CommonQueryContract setParameter (String name , Calendar value , TemporalType temporalType ) {
1083- locateBinding ( name , Calendar . class , value ).setBindValue ( value , temporalType );
1072+ locateBinding ( name , temporalType , value ).setBindValue ( value , temporalType );
10841073return this ;
10851074}
10861075
10871076@ Override @ Deprecated
10881077public CommonQueryContract setParameter (String name , Date value , TemporalType temporalType ) {
1089- locateBinding ( name , Date . class , value ).setBindValue ( value , temporalType );
1078+ locateBinding ( name , temporalType , value ).setBindValue ( value , temporalType );
10901079return this ;
10911080}
10921081
10931082@ Override @ Deprecated
10941083public CommonQueryContract setParameter (int position , Calendar value , TemporalType temporalType ) {
1095- locateBinding ( position , Calendar . class , value ).setBindValue ( value , temporalType );
1084+ locateBinding ( position , temporalType , value ).setBindValue ( value , temporalType );
10961085return this ;
10971086}
10981087
10991088@ Override @ Deprecated
11001089public CommonQueryContract setParameter (int position , Date value , TemporalType temporalType ) {
1101- locateBinding ( position , Date . class , value ).setBindValue ( value , temporalType );
1090+ locateBinding ( position , temporalType , value ).setBindValue ( value , temporalType );
11021091return this ;
11031092}
11041093
@@ -1122,8 +1111,7 @@ public <P> CommonQueryContract setParameterList(String name, Collection<? extend
11221111
11231112@ Override
11241113public <P > CommonQueryContract setParameterList (String name , Collection <? extends P > values , Type <P > type ) {
1125- locateBinding ( name , type .getJavaType (), values )
1126- .setBindValues ( values , (BindableType <P >) type );
1114+ locateBinding ( name , type .getJavaType (), values ).setBindValues ( values , (BindableType <P >) type );
11271115return this ;
11281116}
11291117
0 commit comments