HHH-16954 introduce HibernateCriteriaBuilder.parameterList()

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-09-07 22:53:50 +02:00
parent 7ea607a7c8
commit e55c05f0b4
5 changed files with 59 additions and 9 deletions

View File

@ -25,7 +25,6 @@ import org.hibernate.query.NullPrecedence;
import org.hibernate.query.SortDirection;
import org.hibernate.query.sqm.FrameKind;
import org.hibernate.query.sqm.TemporalUnit;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.AbstractQuery;
@ -640,6 +639,25 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
@Override
<T> JpaParameterExpression<T> parameter(Class<T> paramClass, String name);
/**
* Create a multivalued parameter accepting multiple arguments
* packaged together as a {@link List}.
* @param paramClass the type of each argument to the parameter
* @param <T> the type of each argument to the parameter
* @since 7.0
*/
<T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass);
/**
* Create a multivalued parameter accepting multiple arguments
* packaged together as a {@link List}.
* @param paramClass the type of each argument to the parameter
* @param name the parameter name
* @param <T> the type of each argument to the parameter
* @since 7.0
*/
<T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass, String name);
@Override
JpaExpression<String> concat(Expression<String> x, Expression<String> y);

View File

@ -679,6 +679,16 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
return criteriaBuilder.concat( x, y );
}
@Override
public <T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass) {
return criteriaBuilder.parameterList( paramClass );
}
@Override
public <T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass, String name) {
return criteriaBuilder.parameterList( paramClass, name );
}
@Override
public JpaExpression<String> concat(Expression<String> x, String y) {
return criteriaBuilder.concat( x, y );

View File

@ -63,6 +63,7 @@ import org.hibernate.query.criteria.JpaCteCriteriaAttribute;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaFunction;
import org.hibernate.query.criteria.JpaOrder;
import org.hibernate.query.criteria.JpaParameterExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSearchOrder;
import org.hibernate.query.criteria.JpaSelection;
@ -1644,6 +1645,17 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
return new JpaCriteriaParameter<>( name, parameterType, notBasic, this );
}
@Override
public <T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass) {
return parameterList( paramClass, null );
}
@Override
public <T> JpaParameterExpression<List<T>> parameterList(Class<T> paramClass, String name) {
final BindableType<List<T>> parameterType = new MultiValueParameterType<>( (Class<List<T>>) (Class) List.class );
return new JpaCriteriaParameter<>( name, parameterType, true, this );
}
@Override
public SqmExpression<String> concat(List<Expression<String>> expressions) {
//noinspection unchecked

View File

@ -24,7 +24,6 @@ import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.sql.ast.tree.cte.CteMaterialization;
import org.hibernate.sql.ast.tree.cte.CteSearchClauseKind;
import org.hibernate.testing.orm.domain.gambit.BasicEntity;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.hibernate.testing.orm.domain.StandardDomainModel;
@ -32,19 +31,14 @@ import org.hibernate.testing.orm.domain.contacts.Address;
import org.hibernate.testing.orm.domain.contacts.Contact;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -510,8 +504,7 @@ public class CteTests {
scope.inTransaction(
session -> {
final HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
//noinspection unchecked
final JpaParameterExpression<List<Integer>> param = cb.parameter( (Class<List<Integer>>) (Class<?>) List.class );
final JpaParameterExpression<List<Integer>> param = cb.parameterList( Integer.class );
final JpaCriteriaQuery<Tuple> cq = cb.createTupleQuery();
final JpaCriteriaQuery<Tuple> baseQuery = cb.createTupleQuery();

View File

@ -16,6 +16,7 @@ import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import jakarta.persistence.criteria.ParameterExpression;
import org.hibernate.dialect.CockroachDialect;
import org.hibernate.community.dialect.DerbyDialect;
import org.hibernate.dialect.PostgreSQLDialect;
@ -514,4 +515,20 @@ public class CriteriaBuilderNonStandardFunctionsTest {
assertEquals( eob.getTheLocalDateTime().truncatedTo( ChronoUnit.SECONDS ), result.get( 6 ) );
} );
}
@Test
@JiraKey("HHH-16954")
public void testParameterList(SessionFactoryScope scope) {
scope.inTransaction( session -> {
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<EntityOfBasics> from = query.from(EntityOfBasics.class);
ParameterExpression<List<Integer>> ids = cb.parameterList(Integer.class);
query.where( from.get("id").in(ids));
assertEquals(3,
session.createQuery( query )
.setParameter(ids, List.of(2, 3, 5))
.getResultCount());
} );
}
}