Fix function parameters type determination

This commit is contained in:
Andrea Boriero 2022-01-27 12:56:14 +01:00 committed by Andrea Boriero
parent b721aa9b86
commit 971d1ea2f4
3 changed files with 85 additions and 1 deletions

View File

@ -18,6 +18,7 @@ import org.hibernate.query.QueryParameter;
import org.hibernate.query.spi.QueryParameterBinding;
import org.hibernate.query.spi.QueryParameterBindingValidator;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
import org.hibernate.type.descriptor.java.CoercionException;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.TemporalJavaType;
@ -142,7 +143,9 @@ public class QueryParameterBindingImpl<T> implements QueryParameterBinding<T>, J
final SqmExpressible<? extends T> sqmExpressible = parameterType.resolveExpressible( sessionFactory );
assert sqmExpressible != null;
if ( sqmExpressible instanceof AttributeConverterTypeAdapter ) {
return value;
}
return sqmExpressible.getExpressibleJavaType().coerce( value, this );
}

View File

@ -21,6 +21,7 @@ import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmFunction;
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
@ -95,6 +96,15 @@ public class ParameterCollector extends BaseSemanticQueryWalker {
);
}
@Override
public Object visitFunction(SqmFunction<?> sqmFunction) {
SqmExpressibleAccessor<?> current = inferenceBasis;
inferenceBasis = null;
super.visitFunction( sqmFunction );
inferenceBasis = current;
return sqmFunction;
}
private <T> BindableType<T> getInferredParameterType(JpaCriteriaParameter<?> expression) {
BindableType<?> parameterType = null;
if ( inferenceBasis != null ) {

View File

@ -0,0 +1,71 @@
/*
* 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.jpa.compliance;
import java.util.List;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
@Jpa(
annotatedClasses = {
CriteriaFunctionParametersBindingTest.Person.class
}
)
public class CriteriaFunctionParametersBindingTest {
@Test
public void testParameterBinding(EntityManagerFactoryScope scope) {
scope.inEntityManager(
entityManager -> {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery( Person.class );
final Root<Person> person = criteriaQuery.from( Person.class );
criteriaQuery.where( criteriaBuilder.equal(
person.get( "name" ),
criteriaBuilder.substring(
criteriaBuilder.parameter( String.class, "string" ),
criteriaBuilder.parameter( Integer.class, "start" )
)
) );
criteriaQuery.select( person );
final TypedQuery<Person> query = entityManager.createQuery( criteriaQuery );
query.setParameter( "string", "andrea" );
query.setParameter( "start", 2 );
List<Person> people = query.getResultList();
}
);
}
@Entity(name = "Person")
@Table(name = "PERSON_TABLE")
public static class Person {
@Id
private Integer id;
private String name;
}
}