【问题标题】:Generic criteriaUpdate set boolean = !boolean通用标准更新集 boolean = !boolean
【发布时间】:2018-11-10 16:36:01
【问题描述】:

我想使用条件更新来创建这样的更新查询:

UPDATE <SOME TABLE>
SET SELECTED = !SELECTED
WHERE
[DYNAMIC QUERY HERE]

我能得到的最接近的是代码:

public <T> Query createRevertSelectionQuery(Class<T> clazz, EntityManager em, Specification<T> s) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaUpdate<T> criteriaUpdate = cb.createCriteriaUpdate(clazz);
    Root<T> root = criteriaUpdate.from(clazz);
    Predicate p = cb.and(new Predicate[] {s.toPredicate(root, null, cb)});
    Expression<Boolean> e =cb.not((root.get("selected").as(Boolean.class)));
    Path<Boolean> selected = root.get("selected");
    criteriaUpdate.set(selected, e);
    criteriaUpdate.where(p);
    Query q = em.createQuery(criteriaUpdate);       
    return q;       
}

但它失败了,因为我收到以下查询:

update com.redknee.suspense.mgt.model.Moc as generatedAlias0 
set generatedAlias0.selected = generatedAlias0.selected <> true 
where 
[dynamic query]

给我错误

org.hibernate.hql.internal.ast.QuerySyntaxException:意外令牌:在第 1 行,第 118 列附近

有人可以帮忙吗?

【问题讨论】:

  • 看起来像弹簧,弹簧靴?添加相关标签以询问是否是。规格如何?
  • 谢谢@pirho。规范如下:我想使用“规范 s”中指定的 where 子句更新通用实体 T 设置列“selected”=“NOT(selected)”如果我可以设置“set generatedAlias0.selected = (generatedAlias0. selected true)" 可能会起作用,但我不知道该怎么做...
  • 没有问题。如果有其他谓词,规范似乎只用于附加。
  • 方言可能有误?

标签: spring-boot spring-data-jpa criteria criteria-api


【解决方案1】:

我不确定这是否是一个错误,或者它只是不应该以这种方式使用。

在 where 子句中 NOT 和任何其他操作数都像魅力一样工作。但是,无论您尝试什么,Hibernate 查询构建器似乎总是会优化那些括号(在我看来,始终使用括号可能仍然是一个好习惯,但这只是一种意见)。

强制使用括号的一种方法是使用 JPA Subquery。请参见下面的示例。请注意,我根据自己的喜好稍微更改了 JPA 对象名称,并且不包括 Specification,因为它与此解决方案无关:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<T> update = cb.createCriteriaUpdate(clazz);
Root<T> from = update.from(clazz);
Path<Boolean> selected = from.get("selected");

// Subquery just "joins back" to the same row and
// returns a negated boolean value of "selected" from the original row
Subquery<Boolean> subSelect = update.subquery(Boolean.class);
Root<T> subFrom = subSelect.from(clazz);
subSelect.select(cb.not(selected));
subSelect.where(cb.equal(from.get("id"), subFrom.get("id")));

update.set(selected, subSelect);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 2021-01-10
    • 2021-10-08
    相关资源
    最近更新 更多