Re-using Query instance for multiple executeUpdate calls

To workaround the limited numbers of SQL parameters that can be passed to databases we are using a set of utility methods to execute a query multiple times with a different set of parameter values. This worked fine in Hibernate 5, but results in an exception using Hibernate 6.

Utility methods:

public static void executeClusteredUpdate(List<?> targets, Query query, String targetsParamName)
{
	int index = 0;
	while (hasMoreElements(targets, index))
	{
		List<?> subTargets = getNextElements(targets, index);
		index += 500;

		query.setParameter(targetsParamName, subTargets).executeUpdate();
	}
}

public static boolean hasMoreElements(Collection<?> objects, int index)
{
	return objects.size() > index;
}

public static <T> List<T> getNextElements(List<T> objects, int index)
{
	return objects.subList(index, Math.min(objects.size(), (index + 500)));
}

Entity:

@Entity
@NamedQuery(name = "ExampleEntity.resetNameByIds",
        query= "UPDATE ExampleEntity ee" +
                "  SET ee.name = null " +
                "WHERE ee.id IN (:ids)")
public class ExampleEntity {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

Execution:

List<Long> ids = new ArrayList<>();
for (int i = 0; i < 10000; i++)
{
	ids.add(-1000L);
}

executeClusteredUpdate(ids, entityManager.createNamedQuery("ExampleEntity.resetNameByIds"), "ids");

Exception:

Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.size()" because "jdbcParamBinds" is null
	at org.hibernate@6.4.4.Final//org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:333)
	at org.hibernate@6.4.4.Final//org.hibernate.query.sqm.internal.SimpleUpdateQueryPlan.executeUpdate(SimpleUpdateQueryPlan.java:63)
	at org.hibernate@6.4.4.Final//org.hibernate.query.sqm.internal.QuerySqmImpl.doExecuteUpdate(QuerySqmImpl.java:705)
	at org.hibernate@6.4.4.Final//org.hibernate.query.sqm.internal.QuerySqmImpl.executeUpdate(QuerySqmImpl.java:675)

When using the Hibernate Test project, a different exception occurs:

java.lang.AssertionError
	at org.hibernate.query.sqm.internal.SqmUtil.createJdbcParameterBindings(SqmUtil.java:406)
	at org.hibernate.query.sqm.internal.SimpleUpdateQueryPlan.executeUpdate(SimpleUpdateQueryPlan.java:63)
	at org.hibernate.query.sqm.internal.QuerySqmImpl.doExecuteUpdate(QuerySqmImpl.java:666)
	at org.hibernate.query.sqm.internal.QuerySqmImpl.executeUpdate(QuerySqmImpl.java:639)

I’m not able to attach the test project ZIP.

Is this a bug or are we doing something that is not allowed? Do you have a different solution for us? Thank you very much in advance!

It’s fixed by HHH-18027 Clear expansions NonSelectQueryPlan.executeUpdate call by beikov · Pull Request #8440 · hibernate/hibernate-orm · GitHub, you should update version to 6.4.9 or 6.5.3.

Thank you very much for the information! You are indeed correct, although 6.5.3 is not released yet.