英文:
CriteriaBuilder giving AND instead of OR in predicate
问题
以下是翻译好的内容:
我想使用 CriteriaUpdate
查询来更新表中的日期字段。
我正在基于在 where in
子句中过滤的一组 ID 进行此更新。
这组 ID 可能大于1000,因此为了避免 ORA-01795(在 in 子句中的1000限制),我将基于999的子列表对 ID 列表进行了分区。
这是我的代码:
@Modifying
public void updateDate(List<Long> ids, Date date) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaUpdate<MyTable> update = builder.createCriteriaUpdate(MyTable.class);
Root root = update.from(MyTable.class);
update.set("dateField", date); // 在 MyTable 实体中存在 dateField。
List<List<Long>> partitionedList = Lists.partition(ids, 999);
List<Predicate> orPredicates = new ArrayList<>();
partitionedList.forEach(partition -> {
Predicate predicate = builder.or(root.get("id").in(partition)); // MyTable 实体的 Id
orPredicates.add(predicate);
});
update.where(orPredicates.toArray(new Predicate[]{}));
entityManager.createQuery(update).executeUpdate();
}
我预期生成的查询应该是这样的:
update myTable set dateField=? where (id in (1, 2, 3.....9999)) OR ((id in (1000, 1001....))
但是生成的查询中有 AND 而不是 OR。
update myTable set dateField=? where (id in (1, 2, 3.....9999)) AND ((id in (1000, 1001....))
我漏掉了什么?
英文:
I want to update a date field in my table using CriteriaUpdate
query.
I'm making this update based on the set of IDs filtered in where in
clause.
This set of IDs can be greater than 1000, so in order to avoid ORA-01795(1000 limit in in clause), I'm partitioning the IDs list based into sub-lists of 999.
Here is my code:
@Modifying
public void updateDate(List<Long> ids, Date date) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaUpdate<MyTable> update = builder.createCriteriaUpdate(MyTable.class);
Root root = update.from(MyTable.class);
update.set("dateField", date); // dateField present in MyTable entity.
List<List<Long>> partitionedList = Lists.partition(ids, 999);
List<Predicate> orPredicates = new ArrayList<>();
partitionedList.forEach(partition -> {
Predicate predicate = builder.or(root.get("id").in(partition)); // Id of MyTable entity
orPredicates.add(predicate);
});
update.where(orPredicates.toArray(new Predicate[]{}));
entityManager.createQuery(update).executeUpdate();
}
I was expecting generated query to be like:
update myTable set dateField=? where (id in (1, 2, 3.....9999)) OR ((id in (1000, 1001....))
But the generated query has AND instead of OR.
update myTable set dateField=? where (id in (1, 2, 3.....9999)) AND ((id in (1000, 1001....))
What am I missing?
答案1
得分: 3
因为您正在使用Java 8的流逻辑,可以这样做:
update.where(builder.or(
Lists.partition(ids, 999).stream()
.map(partition -> root.get("id").in(partition))
.toArray()
));
英文:
Since you're using Java 8 stream logic, do it this way:
update.where(builder.or(
Lists.partition(ids, 999).stream()
.map(partition -> root.get("id").in(partition))
.toArray()
));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论