HHH-15113 Exception setting ParameterExpressions on Update Queries

This commit is contained in:
Andrea Boriero 2022-03-09 13:22:17 +01:00 committed by Sanne Grinovero
parent 741b6b71f1
commit 2d19bdbaf3
2 changed files with 107 additions and 0 deletions

View File

@ -74,6 +74,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmSetJoin; import org.hibernate.query.sqm.tree.domain.SqmSetJoin;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin; import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.expression.ValueBindJpaCriteriaParameter; import org.hibernate.query.sqm.tree.expression.ValueBindJpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic; import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched; import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
@ -1420,6 +1421,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
*/ */
@Override @Override
public <T> SqmExpression<T> value(T value, SqmExpression<? extends T> typeInferenceSource) { public <T> SqmExpression<T> value(T value, SqmExpression<? extends T> typeInferenceSource) {
if ( value instanceof SqmExpression ) {
return (SqmExpression<T>) value;
}
if ( criteriaValueHandlingMode == ValueHandlingMode.INLINE ) { if ( criteriaValueHandlingMode == ValueHandlingMode.INLINE ) {
return literal( value, typeInferenceSource ); return literal( value, typeInferenceSource );
} }
@ -1457,6 +1461,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override @Override
public <T> SqmExpression<T> value(T value) { public <T> SqmExpression<T> value(T value) {
if ( value instanceof SqmExpression ) {
return (SqmExpression<T>) value;
}
if ( criteriaValueHandlingMode == ValueHandlingMode.INLINE ) { if ( criteriaValueHandlingMode == ValueHandlingMode.INLINE ) {
return literal( value ); return literal( value );
} }

View File

@ -0,0 +1,100 @@
package org.hibernate.orm.test.jpa.query;
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.Query;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaUpdate;
import jakarta.persistence.criteria.ParameterExpression;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.metamodel.EntityType;
@Jpa(
annotatedClasses = CriteriaUpdateWithParametersTest.Person.class
)
public class CriteriaUpdateWithParametersTest {
@Test
public void testCriteriaUpdate(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaUpdate<Person> criteriaUpdate = criteriaBuilder.createCriteriaUpdate( Person.class );
final Root<Person> root = criteriaUpdate.from( Person.class );
final ParameterExpression<Integer> intValueParameter = criteriaBuilder.parameter( Integer.class );
final ParameterExpression<String> stringValueParameter = criteriaBuilder.parameter( String.class );
final EntityType<Person> personEntityType = entityManager.getMetamodel().entity( Person.class );
criteriaUpdate.set(
root.get( personEntityType.getSingularAttribute( "age", Integer.class ) ),
intValueParameter
);
criteriaUpdate.where( criteriaBuilder.equal(
root.get( personEntityType.getSingularAttribute( "name", String.class ) ),
stringValueParameter
) );
final Query query = entityManager.createQuery( criteriaUpdate );
query.setParameter( intValueParameter, 9 );
query.setParameter( stringValueParameter, "Luigi" );
query.executeUpdate();
}
);
}
@Test
public void testCriteriaUpdate2(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaUpdate<Person> criteriaUpdate = criteriaBuilder.createCriteriaUpdate( Person.class );
final Root<Person> root = criteriaUpdate.from( Person.class );
final ParameterExpression<Integer> intValueParameter = criteriaBuilder.parameter( Integer.class );
final ParameterExpression<String> stringValueParameter = criteriaBuilder.parameter( String.class );
criteriaUpdate.set( "age", intValueParameter );
criteriaUpdate.where( criteriaBuilder.equal( root.get( "name" ), stringValueParameter ) );
final Query query = entityManager.createQuery( criteriaUpdate );
query.setParameter( intValueParameter, 9 );
query.setParameter( stringValueParameter, "Luigi" );
query.executeUpdate();
}
);
}
@Entity(name = "Person")
public static class Person {
@Id
private String id;
private String name;
private Integer age;
public Person() {
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
}