HHH-15113 Exception setting ParameterExpressions on Update Queries
This commit is contained in:
parent
c3cefd74ca
commit
f78ae8b4c6
|
@ -8,6 +8,7 @@ package org.hibernate.query.criteria.internal;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.criteria.CriteriaUpdate;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Path;
|
||||
|
@ -69,9 +70,15 @@ public class CriteriaUpdateImpl<T> extends AbstractManipulationCriteriaQuery<T>
|
|||
@SuppressWarnings("unchecked")
|
||||
public CriteriaUpdate<T> set(String attributeName, Object value) {
|
||||
final Path attributePath = getRoot().get( attributeName );
|
||||
final Expression valueExpression = value == null
|
||||
? criteriaBuilder().nullLiteral( attributePath.getJavaType() )
|
||||
: criteriaBuilder().literal( value );
|
||||
final Expression valueExpression;
|
||||
if ( value instanceof Expression ) {
|
||||
valueExpression = (Expression) value;
|
||||
}
|
||||
else {
|
||||
valueExpression = value == null
|
||||
? criteriaBuilder().nullLiteral( attributePath.getJavaType() )
|
||||
: criteriaBuilder().literal( value );
|
||||
}
|
||||
addAssignment( attributePath, valueExpression );
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Parameter;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
|
||||
|
@ -22,6 +23,7 @@ import org.hibernate.internal.util.StringHelper;
|
|||
import org.hibernate.internal.util.collections.Stack;
|
||||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.query.criteria.LiteralHandlingMode;
|
||||
import org.hibernate.query.criteria.internal.expression.ParameterExpressionImpl;
|
||||
import org.hibernate.query.criteria.internal.expression.function.FunctionExpression;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
|
@ -107,8 +109,9 @@ public class CriteriaCompiler implements Serializable {
|
|||
);
|
||||
}
|
||||
else {
|
||||
final String name = generateParameterName();
|
||||
parameterInfo = new ExplicitParameterInfo(
|
||||
generateParameterName(),
|
||||
name,
|
||||
null,
|
||||
criteriaQueryParameter.getJavaType()
|
||||
);
|
||||
|
@ -132,6 +135,9 @@ public class CriteriaCompiler implements Serializable {
|
|||
}
|
||||
|
||||
public void bind(TypedQuery typedQuery) {
|
||||
if ( literal instanceof Parameter ) {
|
||||
return;
|
||||
}
|
||||
typedQuery.setParameter( parameterName, literal );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
|||
public class ParameterExpressionImpl<T>
|
||||
extends ExpressionImpl<T>
|
||||
implements ParameterExpression<T>, Serializable {
|
||||
private final String name;
|
||||
private String name;
|
||||
private final Integer position;
|
||||
|
||||
public ParameterExpressionImpl(
|
||||
|
@ -75,6 +75,9 @@ public class ParameterExpressionImpl<T>
|
|||
@Override
|
||||
public String render(RenderingContext renderingContext) {
|
||||
final ExplicitParameterInfo parameterInfo = renderingContext.registerExplicitParameter( this );
|
||||
if ( name == null && position == null ) {
|
||||
name = parameterInfo.getName();
|
||||
}
|
||||
return parameterInfo.render();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package org.hibernate.jpa.test.query;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaUpdate;
|
||||
import javax.persistence.criteria.ParameterExpression;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
|
||||
@Jpa(
|
||||
annotatedClasses = CriteriaUpdateWithParametersTest.Person.class
|
||||
)
|
||||
@TestForIssue( jiraKey = "HHH-15113")
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue