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!